Zookeeper是⼀个开源的分布式的,为分布式应⽤提供协调的Apache项⽬。
Zookeeper从设计模式⻆度来理解:是⼀个基于观察者模式设计的分布式服务管理框架,它负责存储和管理⼤家都关⼼的数据,然后接受观察者的注册,⼀旦这些数据的状态发⽣变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应
Zookeeper数据模型的结构与Unix⽂件系统很类似,整体上可以看作是⼀颗树,每个节点称作⼀个ZNode。每⼀个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯⼀标识。
提供的服务包括:统⼀命名服务、统⼀配置管理、统⼀集群管理、服务器节点动态上下线、软负载均衡等。
统⼀命名服务:
在分布式环境下,经常需要对应⽤/服务进⾏统⼀命名,便于识别。
例如:IP不容易记住,⽽域名容易记住。
统⼀配置管理:
统⼀集群管理:
分布式环境中,实时掌握每个节点的状态是必要的,可根据节点实时状态做出⼀些调整。ZooKeeper可以实现实时监控节点状态变化:
服务器动态上下线:
客⼾端实时洞察服务上下线变化
负载均衡:
在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客⼾端请求。
(1)Server id(或sid):服务器ID
⽐如有三台服务器,编号分别是1,2,3。编号越⼤在选择算法中的权重越⼤,⽐如初始化启动时就是根据服务器ID进⾏⽐较。
(2)Zxid:事务ID
服务器中存放的数据的事务ID,值越⼤说明数据越新,在选举算法中数据越新权重越⼤。
(3)Epoch:逻辑时钟
也叫投票的次数,同⼀轮投票过程中的逻辑时钟值是相同的,每投完⼀次票这个数据就会增加。
(4)Server状态:选举状态
LOOKING,竞选状态。
FOLLOWING,随从状态,同步leader状态,参与投票。
OBSERVING,观察状态,同步leader状态,不参与投票。
LEADING,主状态。
a.server1 启动
触发⼀次选举,server1投给⾃⼰⼀票,但是总共5台服务器未达到半数3台,所以选举⽆法完成。
投票结果:server1 :1票
状态:server1:LOOKING
b.server2 启动
触发选举,server1和2分别投⾃⼰⼀票,但是server1发现2的id⽐⾃⼰⼤,就更改选票投给server2,此时未达半数,还是LOOKING状态
投票结果:server1 :0票 server2 :2票
状态:server1:LOOKING server2:LOOKING
c.server3启动
触发选举,server1和2和3分别投⾃⼰⼀票,但是server1和2发现3的id⽐⾃⼰⼤,就更改选票投给server3,此时达半数投票,server3当选 leader
投票结果:server1 :0票 server1 :0票 server3 :3票
状态:server1:FOLLOWER server2:FOLLOWER server3:LEADER
d.server4启动
触发选举,server1、2、3已经不是LOOKING,不会更改选票信息,只会交换选票信息
投票结果:server1 :0票 server1 :0票 server3 :3票 server4 :1票
状态:server1:FOLLOWER server2:FOLLOWER server3:LEADER server4:FOLLOWER
e.server5启动
和server4⼀样投票给⾃⼰,但是已经有leader了就结束选举
投票结果:server1 :0票 server1 :0票 server3 :3票 server4 :1票 server5 :1票
状态:server1:FOLLOWER server2:FOLLOWER server3:LEADER server4:FOLLOWER
server5:FOLLOWER
总结:服务器3选为leader,其余是follower,⼀般集群中间的机器当选leader
运⾏期选举与初始状态投票过程基本类似,⼤致可以分为以下⼏个步骤:
(1)状态变更。Leader 故障后,余下的 ⾮ Observer 服务器都会将⾃⼰的服务器状态变更为LOOKING ,然后开始进⼊ Leader选举过程 。
(2)每个Server会发出投票。
(3)接收来⾃各个服务器的投票,如果其他服务器的数据⽐⾃⼰的新会改投票。
(4)处理和统计投票,每⼀轮投票结束后都会统计投票,超过半数即可当选。
(5)改变服务器的状态,宣布当选。
(1)次投票,每台机器都会将票投给⾃⼰。
(2)接着每台机器都会将⾃⼰的投票发给其他机器,如果发现其他机器的zxid⽐⾃⼰⼤,那么就需要改投票重新投⼀次。⽐如server1 收到了三张票,发现server2的xzid为102,pk⼀下发现⾃⼰输了,后⾯果断改投票选server2为⽼⼤。
EPOCH ⼤的直接胜出
EPOCH 相同,事务 id ⼤的胜出
事务 id 相同,服务器 id ⼤的胜出
znode也可以是顺序性的。每⼀个顺序性的znode关联⼀个唯⼀的单调递增整数。这个单调递增整数是znode名字的后缀。
FIY:在分布式系统中,顺序号可以被⽤于为所有事件进⾏全局排序,这样客⼾端可以通过顺序号推断时间的顺序。
客⼾端注册监听它关⼼的⽬录节点,当⽬录节点发⽣变化(数据改变、节点删除、⼦⽬ 录节点增加删除)时,ZooKeeper 会通知客⼾端。监听机制保证 ZooKeeper 保存的任何的数 据的任何改变都能快速的响应到监听了该节点的应⽤程序。
1、监听原理详解
(1)⾸先要有⼀个main()线程
(2)在main线程中创建Zookeeper客⼾端,这时就会创建两个线程,⼀个负责⽹络连接通信(connect),⼀个负责监听(listener) 。
(3)通过connect线程将注册的监听事件发送给Zookeeper。
(4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
(5)Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。
(6) listener线程内部调⽤了process()⽅法。
2、常⻅的监听
(1)监听节点数据的变化
get path [ watch]
(2)监听⼦节点增减的变化
ls path [watch]