标签:lead 最大的 min net 两种 序号 因此 img 告诉
Zookeeper集群完成Leader选举后,会进行Leader和Follower的数据同步(或叫状态同步),完成同步是保证服务器数据一致,可以提供服务的前提,接下来记录下Zookeeper数据同步相关的内容,主要参考文末书籍和博文。
Zookeeper中数据同步一共有四类,如下。
不同的场景,会有不同的数据同步方式,具体选择哪种方式,还需要参考以下三个参数,根据这三个参数的大小对比结果,选择对应的数据同步方式。
上面几个参数的初始化工作,是在数据同步前完成的,如下图所示是看文末书粗略理解的,可能不正确,如有错误请留言批评指正,非常感谢!
首先从Zookeeper内存数据库中获取到请求对应的提议缓存队列,每个proposal都是有对应zxid的,Leader发出的proposal不是直接写入到Follower,而是先会存于缓存队列中,等待Follower一个个的写入。缓存队列中的proposal事务和Leader本地提交的事务保持一致,Follower根据自己的实际情况,对这个proposal队列进行处理。
按照上面的理解,下图中Follower最后处理的zxid即为0x500000004,Leader服务器提交在队列中的最小zxid为0x500000003,最大zxid为0x500000005,因此minCommittedLog为0x500000003,maxCommittedLog为0x500000005。接下来通过比较这几个参数,来决定进行以上哪类数据同步。
场景:上图中的情况,就会走DIFF直接差异化同步,其中peerLastZxid在minCommittedLog和maxCommittedLog之间,这种情况也可以理解为Follower没有同步完Leader存于提议缓存队列的请求,参考文末书籍,接下来Follower和Leader之间会进行如下图所示的多次数据包通信。
场景:这种场景是比较特殊的情况,简单来说就是,当Leader将事务提交到本地事务日志中后,正准备将proposal发送给其他的Follower进行投票时突然宕机,这个时候Zookeeper集群会选取出新的Leader对外服务,并且可能提交了几个事务,此后当老Leader再次上线,新Leader发现它身上有自己没有的事务,就需要回滚抹去老Leader上自己没有的事务,再让老Leader同步完自己新提交的事务,这就是TRUNC+DIFF的场景。
场景:这种情况,就是Learner上的peerLastZxid的值,比maxCommittedLog还要大,这样只需要截取多余的部分事务记录就可以了,无需DIFF差异化同步。
具体过程略,TRUNC回滚同步可以参考以上两种同步方式的过程来理解。
SNAP全量同步在两种情况下会发生。
场景1:Learner上的peerLastZxid的值,比minCommittedLog还要小。
场景2:Leader服务器没有提议缓存队列,peerLastZxid不等于lastProcessedZxid,lastProcessedZxid是Leader服务器数据恢复后最大的zxid(不太明白,暂时放这里)。
这两种情况下Learner和提议缓存队列之间,要么事务有不重叠的地方,要么无法使用提议缓存队列,因此只能使用SNAP全量同步。
全量同步就是将Leader上的全量内存数据都同步到Learner,Leader会先给Learner发送一个SNAP指令,然后Leader会准备数据,从内存数据库中获取全量的数据节点和会话超时时间记录器后,将其序列化后发送给Learner,Learner接收到后对其进行反序列化后存储内存数据库中,完成全量同步,这种方式看上去比较简单粗暴。
PS:Zookeeper状态同步流程的代码主要在LearnerHandler和Learner两个类中。
以上,理解不一定正确,学习就是一个不断认识和纠错的过程。
参考博文:
(1)https://blog.csdn.net/a3125504x/article/details/106727988
(2)https://blog.csdn.net/weixin_36145588/article/details/75043611
(3)《从Paxos到Zookeeper-分布式一致性原理与实践》数据同步
标签:lead 最大的 min net 两种 序号 因此 img 告诉
原文地址:https://www.cnblogs.com/youngchaolin/p/13211752.html