zookeeper2==zookeeper源码阅读,集群如何选举出LEADER

上一篇已经搭建好了环境,这篇研究下集群是怎么进行选举的。

源码分析:

首先将三台机器的data目录下除了myid之外的都清掉,从零开始启动。

先启动ZK1

然后顺着main阅读源码

org.apache.zookeeper.server.quorum.QuorumPeer#start

zookeeper2==zookeeper源码阅读,集群如何选举出LEADER_第1张图片

org.apache.zookeeper.server.quorum.QuorumPeer#run

开始不停读取收到的选票,并且找出LEADER是谁

org.apache.zookeeper.server.quorum.FastLeaderElection#lookForLeader 

该方法就是根据收到选票的情况,执行不同的方法,本处因为是从零启动,所以第一条消息肯定是都在LOOKING:

如果收到的选票中,他说他也正在LOOKING,那么就比较我们两个的票,根据轮次等决定该信谁的,两人商量好后,我再将这个结果广播出去。

zookeeper2==zookeeper源码阅读,集群如何选举出LEADER_第2张图片

 zookeeper2==zookeeper源码阅读,集群如何选举出LEADER_第3张图片

选举过程测试和结果:

清空ZK1和ZK2的data目录下的日志,然后先启动ZK1然后启动ZK2,可以从双方的日志中看到双方进行了一些投票交流,最终确定了ZK2是LEADER。我这在日志里加了个可以打印纳秒的时间戳,就可以清晰看到这样的启动顺序投票过程是怎样的,按先后顺序排列如下:

391479069200 ZK1 Adding vote: from=1, proposed leader=1, proposed zxid=0x0, proposed election epoch=0x1
--1号投自己是LEADER并发送给了自己
397054901700 ZK2 Adding vote: from=2, proposed leader=2, proposed zxid=0x0, proposed election epoch=0x1
--2号投自己是LEADER并发送给了自己
397059044000 ZK2 Adding vote: from=1, proposed leader=1, proposed zxid=0x0, proposed election epoch=0x1
--1号投自己是LEADER并发送给了2号
397059869100 ZK1 Adding vote: from=2, proposed leader=2, proposed zxid=0x0, proposed election epoch=0x1
--2号投自己是LEADER并发送给了1号,1号收到消息后发现两个人都在LOOKING,轮次和ZXID都一样,那就信服务器ID大的,所以1号也转投给2号
397060112400 ZK2 Adding vote: from=1, proposed leader=2, proposed zxid=0x0, proposed election epoch=0x1
--1号转投2号是LEADER并发给了2号,2号在这里调用voteSet.hasAllQuorums()会发现已经有节点收到了超过一半也就是3/2的票,所以就会认为选举完成找到了LEADER。
397060227800 ZK1 Adding vote: from=1, proposed leader=2, proposed zxid=0x0, proposed election epoch=0x1
--1号转投2号是LEADER并发给了自己,在这里调用voteSet.hasAllQuorums()会发现已经有节点收到了超过一半也就是3/2的票,所以就会认为选举完成找到了LEADER。

可以发现,上述选举过程中并没有用到ZAB协议。

选举成功后:

找到LEADER后,ZK1修改自己的状态为FOLLOWER(setPeerState(proposedLeader, voteSet);)

ZK1跳出里层循环回到org.apache.zookeeper.server.quorum.QuorumPeer#run

ZK1下一个循环发现自己是FOLLOWER了,

ZK2下一个循环发现自己是LEADER了,

分别执行如下逻辑。下篇文章再来分析了。

zookeeper2==zookeeper源码阅读,集群如何选举出LEADER_第4张图片


 

你可能感兴趣的:(zookeeper,zookeeper,分布式,云原生)