ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【闲聊杂谈】Zookeeper中的ZAB协议

2021-10-06 13:31:54  阅读:198  来源: 互联网

标签:ZAB Zookeeper 杂谈 follower 集群 myid leader cZxid


1、Zookeeper ZAB 有主

上一篇中我们详细讲解了Paxos算法,而在Zookeeper中基于Paxos算法做了一个更简单的实现——ZAB(Zookeeper Atomic Broadcast)协议,可以认为是Paxos算法的一个精简版,更容易实现数据在分布式情况下的同步。

什么叫 Atomic ?Atomic 的意思是——原子,指的是没有中间状态,要么全部成功,要么全部失败,没有中间模棱两可的状态。

什么叫 Broadcast ?Broadcast 的意思是——广播,意味着这个集群里面是分布式多节点,并且在这个集群中广播不代表全部知道(比如像UDP协议走的就是广播协议,它不能确定对方每个人都收到)。

假设在一个Zookeeper集群中有1台leader和2台follower:

① 一个客户端对一台follower发起了一个写操作创建一个节点;

② follower将这个写请求转发给leader进行处理;

③ leader收到写请求,创建一个cZxid:1

④ leader通过广播告诉所有的follower将这个写请求创建日志记录

    4.1)Zookeeper的数据保存在内存中,但是日志记录却是在磁盘中。所以这一步触发的是在磁  盘中写入日志记录,而并没有在内存中创建出节点;

    4.2)在这一步的过程当中,leader使用了队列。在分布式情况下,任何节点之间的通信都有可能成功,可能失败,可能网络延迟等,所以引入了队列的机制。在leader当中对连接的每一个follower都维护了一个发送队列, leader所广播的每一步操作都放入这个队列中。

⑤ 其中一台follower在收到leader广播之后,会回复leader说知道了,在收到这个明确的回复之后,加上leader自己本身的这一票,也就是说在3台集群中已经有2台达成一致,满足过半通过;

⑥  leader再次通过队列广播follower开始真正在内存中创建节点;

⑦ follower创建完节点以后,会最终给leader回复一个OK,说明已经节点创建成功。

在上述的过程中,虽然只有一台follower给leader回复,另外一台follower可能因为网络延迟的原因没有给leader明确的回复,但是只要达成过半通过后leader广播给所有follower的队列中的命令是一样的。也就是说即便没有回复leader的那个follower,只要将队列中的消息按照顺序消费完,最终它的数据和别人一模一样,从而达成最终一致性。

上述全部完成以后,最终给客户端返回OK。

2、Zookeeper ZAB 选主

上一篇中在介绍Paxos算法的时候,我说leader的选举比较麻烦一两句话说不清楚,现在我们来好好唠一唠这个leader是如何选取出来的。

leader的选举一般来说分为两个场景:

① 集群第1次启动的时候,没有leader需要选出一个leader;

② 集群重启的时候或者leader宕机以后,需要重新选出一个leader。

之前在安装Zookeeper的时候,给每一个Zookeeper的实例都有创建一个myid; leader在每一次进行数据写入的时候,都会发起一个cZxid。基于这些已有的条件之后,我们先来想一想,当从一个集群之中要想选出一个leader的话,这个leader需要满足哪些条件?

首先,当选leader的这个实例必须是数据最全的:针对cZxid这个维度,也就是cZxid号最高;其次,无果这个集群网络非常好,每一个实力之间的通讯都非常的麻利,所有人的数据都是一样的全,那这个时候选leader就是论资排辈,也就是myid号最高。

假设在一个Zookeeper集群中:第一次启动集群,还没有leader

第一台:myid - 1,cZxid - 0

第二台:myid - 2,cZxid - 0

第三台:myid - 3,cZxid - 0

第四台:myid - 4,cZxid - 0

当你启动这个集群的时候,肯定是一台机器一台机器的去启动。而在启动第1台和第2台的时候,只有两台建立连接,但是两台各自为阵,所以没有办法选出一个leader。当启动第3台的时候,有三台两两连接,那么这个时候就已经可以产生过半通过了,此时大家的cZxid都是0,那么就看myid,谁的myid最大谁就是leader。这就是第1个场景:在集群第1次启动的时候选出一个leader的过程。

相比较于第1个场景leader的选举,在第2个场景中集群重启或者leader宕机以后,再次选出新的leader就会比较复杂一点。

假设还是那个Zookeeper集群中:第四台是leader

第一台:myid - 1,cZxid - 8

第二台:myid - 2,cZxid - 8

第三台:myid - 3,cZxid - 7

第四台:myid - 4,cZxid - 8

那么这个集群现在遇到这么一个场景:第1台、第2台的cZxid和leader一样,第3台还没有达成最终一致性的时候,leader宕机了,那么leader宕机以后对于每个follower维护的队列就没有了,第3台永远存活在低版本的cZxid中(其它都是8,只有3是7)。

而恰巧第3台最先发现leader宕机,于是第3台立马先投自己一票,然后再将自己的myid和cZxid发送给第1台和第2台。

第1台和第2台收到第3台发过来的消息,然后和自己的myid和cZxid比较,发现cZxid没自己的大,废止对第3台的投票,并且通过广播将自己的cZxid返回给第3台,告诉第3台说你不行让我来。也就是说第1台和第2台都会被动触发发起对自己的投票,并广播出去让别人为自己投票。

当第1台收到第2台的广播,同样的也会和之前一样去比较myid和cZxid,发现你的cZxid和我的cZxid一样,但是你的myid比我大,那么第1台就会废弃之前自己对自己的投票,并且给第2台投一票。同样的当第2台接收到第1台的广播的时候,也会去比较myid和cZxid,发现你的cZxid和我的cZxid一样大,但是你的myid没有我的myid大,就会继续保持自己对自己的投票。所以很快所有的follower都会给第2台投票,第二台立马就会变成leader。

所以在Zookeeper的集群中,其实任何一个follower发现leader宕机以后无论是谁发现的也好,无论发起的这台机器的cZxid是否足够高也好,只要发现了就会发起投票,这样的设计确保了在足够短的时间内发现leader宕机并且发起投票。就算发起这个投票的机器本身cZxid不够高也没有关系,如果你不够格做leader,就会引发另外够格的机器发起自己的投票,这就是Zookeeper集群可以在不到200毫秒的时间内选出一个leader的原因。

标签:ZAB,Zookeeper,杂谈,follower,集群,myid,leader,cZxid
来源: https://blog.csdn.net/FeenixOne/article/details/120622111

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有