这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
上篇文章我们把zookeeper的一致性算法做了解释,leader选举的过程别人比我说的好多了,让我们图例来说明一下(以下选举实例来源,原作者:雷明 ):
节点1、2、3启动后,都进入looking状态,开始leader选举。每个节点推荐的leader都是自己;逻辑时钟logicalclock值都为1;proposedZxid值都为1;proposedEpoch波次值都为1;投票列表为每个节点投自己的一票(1->1,2->2,3->3)。节点1首先向2、3发送自己的投票消息
节点2、3收到节点1的投票消息,首先查看1的状态,发现1处于looking状态。接下来,判断1发来的electionEpoch和本地逻辑时钟logicalclock的大小,发现两者相等(都为1)。接着判断leader、zxid、peerEpoch和本地proposedLeader、proposedZxid、proposedEpoch的大小,节点2发现节点1推荐的leader的id比自己小(1<2),节点3也发现节点1推荐的leader的id比自己的小(1<3),因此不用更新自己的投票。接下来,节点2、3把节点1的投票放入自己的投票列表中,这样,节点2收到的投票的列表为:
1->1
2->2
节点3的为:
1->1
3->3
节点2、3再判断此次投票是否可以结束,发现不能结束。
节点2向节点1、3发送自己的投票信息,节点3由于发送线程的故障原因,投票信息一直没有出去
在2发出的投票信息中,选择的leader是它自己。
节点1、3收到节点2的投票消息。节点1比较自己的logcalclock和节点2发来的electionEpoch的大小,二者相等,接下来比较leader、zxid、peerEpoch和本地proposedLeader、proposedZxid、proposedEpoch的大小,发现节点2推荐的leader的id(2)比自己的proposedLeader(1)大,于是更新自己的选票,将proposedLeader改为2。然后,节点1将2的选票(2->2)放入自己收到的投票箱中,接着判断投票是否可以结束,由于节点2被超过半数的节点选择(1、2),因此选举可以结束,由于自己不是leader,节点1将自己的状态改为following。
节点3比较自己的logcalclock和节点2发来的electionEpoch的大小,二者相等,接下来比较leader、zxid、peerEpoch和本地proposedLeader、proposedZxid、proposedEpoch的大小,发现节点2推荐的leader的id(2)比自己的proposedLeader(3)小,不用更新自己的选票。然后,节点3将2的选票(2->2)放入自己收到的投票箱中,接着判断投票是否可以结束,由于没有节点获得超过半数的选票,因此选举继续。
此时,节点1选的leader已经变为2,而且节点1的状态已经变成following。
节点2在收到节点1的选票信息后,判断节点1的状态,发现为following,这表明,节点1已经认为leader选出来了,并且是2。节点2首先更新自己的收票箱,将1的投票改为2,接着,判断选举是否结束,发现确实可以结束,节点2就更新自己的状态,由于发现自己是被半数以上人推荐的leader,因此把自己的状态改为leading。
同样,节点3在收到节点1的投票信息后,判断节点1的状态,发现为following,这表明,节点1已经认为leader选出来了,并且是2。节点3首先更新自己的收票箱,将1的投票改为2,接着,判断选举是否结束,发现确实可以结束,节点3就更新自己的状态,由于发现自己不是被半数以上人推荐的leader,因此把自己的状态改为following。