1)zookeeper是分布式协调工具
2)zookeeper=文件系统+通知机制
[1]文件系统:由znode组成
[2]通知机制:客户端可以监控znode子目录或znode中存储的内容,一旦监听的东西发生变化,会收到Zookeeper的通知,客户端从而可以做出相应反应.
2.特点1)zookeeper是server组成的集群,会从server选举出一个leader,其余为follower.
[1]leader负责投票的发起和决议,更新系统的状态.
[2]follower负责在选举leader过程中参与投票.接收客户端请求并向客户端返回结果.
2)集群只要有半数以上节点存活,zookeeper集群就能正常服务.
3)全局数据一致:每个server存储相同的数据,客户端无论连接哪个server,看到的数据都是一样的.
4)数据更新原子性:一次数据更新要么成功,要么失败.
5)更新请求顺序进行:来自同一个客户端的更新请求按其发送顺序一次执行.
6)实时性:客户端能读到最新的数据(在一定的时间范围内).
3.节点的类型1.持久化目录节点(persistent)
客户端与zookeeper断开连接后,该节点依旧存在.
2.持久化顺序编号目录节点(persistent_sequential)
该节点创建时名称进行顺序编号,客户端与zookeeper断开连接后,该节点依旧存在.
3.临时目录节点(ephemeral)
客户端与zookeeper端开连接后,该节点删除
4.临时顺序编号目录节点(ephemeral_sequential)
该节点创建时名称进行顺序编号,客户端与zookeeper端开连接后,该节点删除。
4.zookeeper几个服务器节点单数机制:2n+1,安装奇数台
10台服务器:3台
20台服务器:5台
100台服务器:11台
5.选举机制 1.zookeeper服务器启动时期的Leader选举这里选取3台机器组成的服务器集群为例,在集群初始化阶段,当有一台服务器server1启动时,其单独无法进行leader的选举。
当第二台服务器server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程.选举过程如下:
1)每个server发出一个投票,由于是初始情况,server1和server2都会将自己作为Leader服务器来进行投票,每次投票会包含所有推举的服务器的myid和zxid,使用(sid,zxid)来表示,此时server1的投票为(1,0),server2的投票为(2,0),然后各自将这个投票发给集群中的其他机器.
2)接收来自各个服务器的投票,集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票,是否来自LOOKING状态的服务器.
3)处理投票.针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下:
优先检查ZXID,ZXID比较大的服务器优先作为LEADER.
如果ZXID相同,那么就比较sid,sid较大的服务器作为Leader服务器.
对于server1而言,它的投票是(1,0),接收server2的投票为(2,0),首先会比较两者的ZXID,均为0,再比较myid,此时server2的myid最大,于是更新自己的投票为(2,0),然后重新投票,对于server2而言,其无需更新自己的投票.
4)统计投票,每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接收到相同的投票信息,对于server1 server2而言,都统计出集群中已有两台机器接收到了(2,0)的投票信息,此时便认为已经选出了Leader.
5)改变服务器状态.一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就更新自己的状态为FOLLOWING,如果是LEADER,就变更为LEADING.
2.服务器运行时期的Leader选举 集群中已经存在Leader此种情况一般都是某台机器启动得比较晚,在其启动之前,集群已经在正常工作,对这种情况,该机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器而言,仅仅需要和Leader机器建立起连接,并进行状态同步即可.
集群中不存在Leader1)第一次投票.无论那种导致Leader选举,集群的所有机器都处于试图选举出一个Leader的状态,即LOOKING状态,LOOKING机器向所有其他机器发送消息,该消息称为投票.投票中包含了SID(服务器的唯一标识)和ZXID(事务ID),(SID,ZXID)形式开标识一次投票信息.假定zookeeper由5台机器组成,SID分别为1,2,3,4,5.ZXID为9,9,9,8,8并且此时SID为2的机器是LEADER,某一刻1,2所在机器出现故障,因此集群开始进行leader选举.在第一次投票时,每台机器都会将自己作为投票对象,于是SID为3,4,5的机器投票情况分别为(3,9) (4,8) (5,8)
2)变更投票
每台机器发出投票后,也会收到其他机器的投票,每台机器会根据一定规则来处理收到的其他机器的投票,并以此来决定是否需要变更自己的投票,这个规则也是整个Leader选举算法的核心所在,其中术语描述如下:
vote_sid:接收到的投票中所推举Leader服务器的SID
vote_zxid:接收到的投票中所推举Leader服务器的ZXID
self_sid:当前服务器自己的SID
self_zxid:当前服务器自己的ZXID
每次对接收到的投票的处理,都是对(vote_sid,vote_zxid)和(self_sid,self_zxid)对比的过程.
规则一:如果vote_zxid大于self_zxid,就认可收到的投票,并再次将该投票发送出去.
规则二:如果vote_zxid小于self_zxid,那么坚持自己的投票,不做任何变更.
规则三:如果vote_zxid=self_zxid,那么就对比两者的sid,如果vote_sid>self_sid那么就认可当前收到的投票,并再次将该投票发送出去.
规则四:如果vote_zxid=self_zxid,并且vote_sid 3)确定leader 经过第二轮投票后,集群中的每台机器都会再次接收到其他机器的投票,然后开始统计投票,如果一台机器收到了超过半数的相同投票,那么这个投票对应的sid机器即为leader,此时server3将成为leader. 注:zxid zxid由两部分组成 高32位为epoch(纪元):每当zookeeper的leader发生一次变换,epoch+1 低32位为counter(计数器):每当数据被更新一次counter+1 1.程序的入口:main()方法对应一个main线程 2.在该main线程中创建zookeeper客户端:new Zookeeper(),创建客户端的同时会创建两个线程: sendThread:发送注册监听事件的线程 eventThread:将变化通知给客户端的线程 3.通过sendThread线程将注册的监听事件发送给zookeeper getChildren("/",true)第一个参数为监听的路径,第二个参数true表示开启监听. 4.将注册的监听事件添加到zookeeper的注册监听器列表中 5.当zookeeper监听到变化时,就会将这个消息发送给eventThread线程 6.eventThread线程内部调用了precess()方法进行业务处理. 注:zookeeper一共有三种方法可以实现Watch: 1)getdata:该方法仅监控对应节点数据的一次变化,可以是该节点中该数据的修改或对该节点的删除. 2)exists(final String path,boolean watcher) 判断该Znode是否存在 开启监听时与getData方法的作用一毛一样 3)getChildren(String path,boolean watch) 该方法用于获取某一路径下的所有的直接子节点,第一个参数为路径,第二个参数为是否监听直接子目录中节点的增删,该方法仅监控对应节点直接子目录的一次变化,且只监控直接子目录下节点的增减情况,不会监控数据的变化. create get ls


![[zookeeper]介绍 | 特点 | 节点的类型 | 服务器几个节点 | 选举机制|监听原理 | 常用命令 [zookeeper]介绍 | 特点 | 节点的类型 | 服务器几个节点 | 选举机制|监听原理 | 常用命令](http://www.mshxw.com/aiimages/31/762174.png)
