Zookeeper原理解析

  1. zookeeper角色
  • 领导者:负责发起投票与系统状态更新,完成集群写操作与数据同步
  • 跟随者:参与投票选举,负责将写请求转发给领导者,并接收客户端请求,相应客户端查询
  • 观察者:不参与选举,转发写请求给leader,接收客户端请求,提升集群读取与相应速度(可忽略)
 
 
         up-7b05e15edb8f87a2b9ef420c3f334a8c6d9.png
 
  1. Zookeeper核心
  • ZAB(Zookeeper Actomic BoardCost)协议:有两种模式(恢复模式与广播模式)
整个zookeeper集群中只有一个节点即Leader将客户端的写操作转化为事物(或提议proposal)。Leader节点再数据写完之后,将向所有的follower节点发送数据广播请求(或数据复制),等待所有的follower节点反馈。在ZAB协议中,只要超过半数follower节点反馈OK,Leader节点就会向所有的follower服务器发送commit消息。即将leader节点上的数据同步到follower节点之上
up-60918a3d4bf50b831901b491530cbc415e8.png
  • 原理:
1. ZAB协议要求每个leader都要经历三个阶段,即发现,同步,广播。
2. 发现:即要求zookeeper集群必须选择出一个leader进程,同时leader会维护一个follower可用列表。将来客户端可以这follower中的节点进行通信。
3. 同步:leader要负责将本身的数据与follower完成同步,做到多副本存储。这样也是体现了CAP中高可用和分区容错。follower将队列中未处理完的请求消费完成后,写入本地事物日志中。
4. 广播:leader可以接受客户端新的proposal请求,将新的proposal请求广播给所有的follower。
 
  • 恢复模式(主节点选举:启动和崩溃恢复的情况下)
选举:
1. Serverid:在配置server时,给定的服务器的标示id。
2. Zxid:服务器在运行时产生的数据id,zxid越大,表示数据越新。
3. Epoch:选举的轮数,即逻辑时钟。随着选举的轮数++
4. Server状态:LOOKING,FOLLOWING,OBSERVING,LEADING
步骤:
1.Server刚启动(宕机恢复或者刚启动)准备加入集群,此时读取自身的zxid等信息。
2.所有Server加入集群时都会推荐自己为leader,然后将(leader id 、 zixd 、 epoch)作为广播信息,广播到集群中所有的服务器(Server)。然后等待集群中的服务器返回信息。
3. 收到集群中其他服务器返回的信息,此时要分为两类:该服务器处于looking状态,或者其他状态。
(1)  服务器处于looking状态
首先判断逻辑时钟 Epoch:
a) 如果接收到Epoch大于自己目前的逻辑时钟(说明自己所保存的逻辑时钟落伍了)。更新本机逻辑时钟Epoch,同时 Clear其他服务发送来的选举数据(这些数据已经OUT了)。然后判断是否需要更新当前自己的选举情况(一开始选择的leader id 是自己)
判断规则rules judging:保存的zxid最大值和leader Serverid来进行判断的。先看数据zxid,数据zxid大者胜出;其次再判断leaderServerid, leader Serverid大者胜出;然后再将自身最新的选举结果(也就是上面提到的三种数据(leader Serverid,Zxid,Epoch)广播给其他server)
b) 如果接收到的Epoch小于目前的逻辑时钟。说明对方处于一个比较OUT的选举轮数,这时只需要将自己的 (leader Serverid,Zxid,Epoch)发送给他即可。
c) 如果接收到的Epoch等于目前的逻辑时钟。再根据a)中的判断规则,将自身的最新选举结果广播给其他 server。
同时Server还要处理2种情况:
a)如果Server接收到了其他所有服务器的选举信息,那么则根据这些选举信息确定自己的状态(Following,Leading),结束Looking,退出选举。
b)   即使没有收到所有服务器的选举信息,也可以判断一下根据以上过程之后最新的选举leader是不是得到了超过半数以上服务器的支持,如果是则尝试接受最新数据,倘若没有最新的数据到来,说明大家都已经默认了这个结果,同样也设置角色退出选举过程。
(2)  服务器处于其他状态(Following, Leading)
a)如果逻辑时钟Epoch相同,将该数据保存到recvset,如果所接收服务器宣称自己是leader,那么将判断是不是有半数以上的服务器选举它,如果是则设置选举状态退出选举过程
b)否则这是一条与当前逻辑时钟不符合的消息,那么说明在另一个选举过程中已经有了选举结果,于是将该选举结果加入到outofelection集合中,再根据outofelection来判断是否可以结束选举,如果可以也是保存逻辑时钟,设置选举状态,退出选举过程。
up-30102fe1631a968ec95ecc855be255fec3a.JPEG
 
 
崩溃恢复:
新选举出来的leader不能包含未提交的proposal,即新选举的leader必须都是已经提交了的proposal的follower服务器节点。同时,新选举的leader节点中含有最高的ZXID。
up-864a67e9cf89f9204c6dbcaaffb4ee839b2.png
 
  • 广播模式(数据同步-类两阶段提交(2pc),但是半数相应即可)
数据一致性:zookeeper采用ZAB协议的核心就是只要有一台服务器提交了proposal,就要确保所有的服务器最终都能正确提交proposal。这也是CAP/BASE最终实现一致性的一个体现。
性能:leader服务器与每个follower之间都有一个单独的队列进行收发消息,使用队列消息可以做到异步解耦。leader和follower之间只要往队列中发送了消息即可。如果使用同步方式容易引起阻塞。性能上要下降很多。
up-190b361eaa0c185bede69717f2f131a22fb.png
Proposal与ZXID:ZXID是一个长度64位的数字,其中低32位是按照数字递增,即每次客户端发起一个proposal,低32位的数字简单加1。高32位是leader周期的epoch编号,至于这个编号如何产生(我也没有搞明白),每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的epoch编号,进行加1,再将低32位的全部设置为0。这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的。
 
             up-a2efc8bda061ec5b66bc6bca8512aa402ba.png
具体步骤如下:
1. 客户端发起一个写操作请求
2. Leader服务器将客户端的request请求转化为事物proposql提案,同时为每个proposal分配一个全局唯一的ID,即ZXID。
3. leader服务器与每个follower之间都有一个队列,leader将消息发送到该队列
4. follower机器从队列中取出消息处理完(写入本地事物日志中)毕后,向leader服务器发送ACK确认。
5. leader服务器收到半数以上的follower的ACK后,即认为可以发送commit
6. leader向所有的follower服务器发送commit消息。
 
 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仔仔1993

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值