赞
踩
zookeeper是一种分布式协调服务,用于管理大型主机。
在分布式环境中协调和管理服务是一个复杂的过程,zookeeper通过其简单的架构和API解决了这个问题。zookeeper允许开发人员专注于核心业务逻辑开发,而不必担心应用的分布式特性。
cp zoo_sample.cfg zoo.cfg # 拷贝一份cfg配置文件,新文件命名为zoo.cfg
# zookeeper时间配置中的基本单位(毫秒) tickTime=2000 # 允许follower初始化连接到leader的最大时长,它表示tickTime的时间倍数,即:initLimit*tickTime initLimit=10 # 允许follower与leader数据同步最大时长,它表示tickTime的时间倍速,即:syncLimit*tickTime syncLimit=5 # zookeeper数据存储目录及日志保存目录(如果没有指明dataLogDir,则日志也保存在这个文件中) dataDir=/tmp/zookeeper # 对客户端提供的端口号 clientPort=2181 # 单个客户端与zookeeper最大并发连接数 maxClientCnxns=60 # 保存的数据快照数量,之外的将会被清除 autopurge.snapRetainCount=3 # 自动触发清除任务时间间隔,单位为小时,默认为0,表示不自动清除 autopurge.purgeInterval=1
# 进入到bin目录中,执行
./zkServer.sh start ../conf/zoo.cfg
./zkServer.sh start ../conf/zoo.cfg
./zkServer.sh status ../conf/zoo.cfg
./zkServer.sh stop ../conf/zoo.cfg
zk中数据是保存在节点上的,节点就是znode,多个znode之间构成了一棵树的目录结构
zk的数据模型是什么样子呢?有点像数据结构中的树,也比较像文件系统的目录。
根路径为 /。不同于树的节点,znode的引用方式是路径引用,类似于文件路径:
这样的层次结构,让每一个znode节点拥有唯一的路径,就像命名空间一样,对不同的信息作出清晰的隔离。
查看zk中的所有节点:
ls /
zk中的znode节点,包含了四个部分:
查看节点的详细信息:
get -s /xxx
节点的详细信息:
zk的数据是运行在内存中的,zk提供了两种持久化机制:
zk通过两种形式的持久化,在恢复时先恢复快照文件中的数据到内存中,再用日志文件中的数据做增量恢复。这样的恢复速度更快
addauth digest xiaowang:123456
# 创建一个节点/test-node,节点数据为abcd,此节点只能由账号为xiangwang,密码为123456的用户操作,可进行创建、删除、写、读、权限设置操作
create /test-node abcd auth:xiangwang:123456:cdwra
在另一个会话中,必须先使用账号密码,才能拥有操作节点的权限
Curator是Netflix公司开源的一套zookeeper客户端框架,Curator是对zookeeper支持最好的客户端框架。Curator封装了大部分zookeeper的功能,比如leader选举、分布式锁等,减少了技术人员在使用zookeeper时的底层细节开发工作。
在Java程序中使用zookeeper,可以引入Curator
<!-- Curator --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <!-- zookeeper --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.7.14</version> </dependency>
curator.retryCount=5 # 重试次数
curator.elapsedTimeMs=5000 # 临时节点的超时时间
curator.connectionString=172.16.253.35:2181 # 连接地址
curator.sessionTimeoutMs=60000 # session超时时间
curator.connectionTimeoutMs=5000 # 连接超时时间
读读共享,读写互斥,写写互斥
如果用上述的上锁方式,只要节点发生变化,就会触发其他节点的监听事件,这样的话对zk的压力非常大,这就是所谓的羊群效应(惊群效应)。
可以调整为链式监听,解决这个问题。
// 将上面的获取读锁改成获取写锁
InterProcessLock interProcessLock = interProcessReadWriteLock.writeLock();
可以把watch机制理解成注册在znode上的触发器。当znode发生变化了(调用了create、delete、setData等方法时),将会触发znode上注册的对应事件,请求znode的客户端会接收到异步通知。
具体交互过程:
客户端使用了NIO的通信模式监听服务端的调用。
create /xxx abc # 创建持久节点/xxx,并设置节点数据为abc
get -w /xxx # 一次性监听节点
ls -w /xxx # 监听目录,创建和删除子节点会收到通知,子节点中新增节点不会收到通知
ls -R -w /xxx # 监听节点所有层级子节点的变化,但内容的变化不会收到通知
zookeeper集群中的节点有三种角色:
搭建4个节点,其中一个节点为observer
# 在/usr/local/zookeeper中创建四个文件
/usr/local/zookeeper/zkdata/zk1# echo 1 > myid
/usr/local/zookeeper/zkdata/zk2# echo 2 > myid
/usr/local/zookeeper/zkdata/zk3# echo 3 > myid
/usr/local/zookeeper/zkdata/zk4# echo 4 > myid
# 不同的zoo.cfg文件中需要更改两处:dataDir和clientPort
...
dataDir=/usr/local/zookeeper/zkdata/zk1 # 数据日志存放路径
clientPort=2181 # 提供给客户端通信的端口
# 2001,2002,2003,2004是用于服务节点之间通信的
# 3001,3002,3003,3004是用于投票选举leader的端口
server.1=172.16.253.55:2001:3001
server.1=172.16.253.55:2002:3002
server.1=172.16.253.55:2003:3003
server.1=172.16.253.55:2004:3004:observer
zookeeper作为非常重要的分布式协调组件,需要进行集群部署,集群中会以一主多从的形式进行部署。zookeeper为了保证数据一致性,使用了ZAB协议(zookeeper atomic broadcast),这个协议解决了zookeeper的崩溃恢复和主从数据同步的问题。
zookeeper集群中的节点上线时,将会进入looking状态,即leader选举状态,会经历过程如下:
总结:zookeeper集群中,一般设置奇数节点比较好,leader选举的时候,比较好判断票数过半的节点
leader建立完后,leader周期性地不断向follower发送心跳(ping命令,没有内容地socket)。当leader崩溃后,follower发现socket通道关闭,于是follower就会从following状态切换到looking状态,重新回到第3节中地leader选举状态。
此时集群不能对外提供服务。
zookeeper在3.1之后的版本用的Netty
zookeeper在数据同步时,追求的并不是强一致性,它保证的是顺序一致性(通过事务id的单调递增)
一个分布式系统中最多只能同时满足一致性、可用性、分区容错性三项中的两项(CP、或者AP)
BASE理论是对CAP理论的延伸,核心思想:即使无法做到强一致性,但应用可以采用适合的方式达到最终一致性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。