再理解ZAB协议

ZAB 协议全称是Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的原子广播协议。ZAB协议的开发设计人员在协议设计之初并没有要求其具有很好的扩展性,最初只是为雅虎公司内部那些高吞吐量、低延迟、健壮、简单的分布式系统场景设计的。在ZooKeeper的官方文档中也指出,ZAB协议并不像Paxos算法那样,是一种通用的分布式一致性算法,它是一种特别为ZooKeeper设计的崩溃可恢复的原子消息广播算法。

假设现在三台机器,客户端发起一个写操作请求,leader服务器将客户端的request请求转化为事物proposql提案,同时为每个proposal分配一个全局唯一的ID,即ZXID(这里用两位数表示前32位和后32位)。

再理解ZAB协议_第1张图片

现在follower1和follower2均收到了p1提案,还没有收到p2和p3。如果此时leader宕机了。也就是说现在在整个集群中只有p1提交了,p2和p3还未提交。根据ZAB协议要求ZooKeeper集群进行崩溃恢复和leader服务器选举。假设此时follwer2被选为leader。此时新的leader会继续发送p2请求,根据ZAB协议,此时p2请求的ZXID在这里会变做为10。

再理解ZAB协议_第2张图片

ZAB协议崩溃恢复要求满足如下2个要求: 
确保已经被leader提交的proposal必须最终被所有的follower服务器提交。 
确保丢弃已经被leader出的但是没有被提交的proposal

针对这个要求,如果让Leader选举算法能够保证新选举出来的Leader服务器拥有集群中所有机器最高编号(即ZXID最大)的事务Proposal,那么就可以保证这个新选举出来的Leader一定具有所有已经提交的提案。更为重要的是,如果让具有最高编号事务Proposal的机器来成为Leader,就可以省去Leader服务器检查Proposal的提交和丢弃工作的这一步操作了。

如果此时新的leader也宕机了,而之前的leader崩溃恢复了。此时之前的leader中的p2和p3两个事务请求会被丢弃。已经被提交的直接根据最大的ZXID同步数据即可。

下面来看ZAB协议是如何处理那些需要被丢弃的事务Proposal的。在ZAB协议的事务编号ZXID设计中,ZXID是一个64位的
数字,其中低32位可以看作是一个简单的单调递增的计数器,针对客户端的每一个事务请求,Leader服务器在产生一个新的事务Proposal的时候,都会对该计数器进行加1操作;而高32位则代表了Leader周期epoch的编号,每当选举产生一个新的 Leader服务器,就会从这个Leader服务器上取出其本地日志中最大事务Proposal的ZXID,并从该ZXID中解析出对应的epoch值,然后再对其进行加1操作,之后就会以此编号作为新的epoch,并将低32位置0来开始生成新的ZXIDo ZAB协议中的这一通过epoch编号来区分Leader周期变化的策略,能够有效地避免不同的Leader服务器错误地使用相同的ZXID编号提出不一样的事务Proposa!的异常情况,这对于识别在Leader崩溃恢复前后生成的Proposal非常有帮助,大大简化和提升了数据恢复流程。

基于这样的策略,当一个包含了上一个Leader周期中尚未提交过的事务Proposal的服务器启动时,其肯定无法成为Leader,原因很简单,因为当前集群中一定包含一个Quorum集合,该集合中的机器一定包含了更高epoch的事务Proposal,因此这台机器的事务Proposal肯定不是最高,也就无法成为Leader了。当这台机器加入到集群中,以Follower角色连接上Leader服务器之后,Leader服务器会根据自己服务器上最后被提交的Proposal来和Follower服务器的Proposal进行比对,比对的结果当然是Leader会要求Follower进行一个回退操作—回退到一个确实已经被集群中过半机器提交的最新的事务Proposal。

ZAB协议可参看:

https://www.cnblogs.com/raphael5200/p/5285583.html

https://www.cnblogs.com/stateis0/p/9062133.html

https://blog.csdn.net/junchenbb0430/article/details/77583955

你可能感兴趣的:(zookeeper)