FastLeaderElection
FastLeaderElection实现了接口Election,选举方法为lookForLeader()
,选举算法的核心逻辑也在该方法中。
数据结构
构造函数
start()
启动选举通信网络
lookForLeader()
选举核心算法
FastLeaderElection.logicalclock
属性用于标识当前leader的选举轮次,zookeeper中规定所有有效的投票必须都在同一轮次中,所以,每发起新一轮的投票都会进行自增操作,如代码中的第2步;初始阶段,每个服务器都会推举自己成为leader,如第3步;初始完成后向集群中的所有服务器发送自己的选票,如第4步;服务器不断接收来自其他服务器的投票,此时如果没有收到任何投票,那么会检查是否连接正常,如果不正常则先建立连接,再重新发送自己的投票,如第6步;在处理选票的时候会根据选票发送服务器的状态进行不同的处理,如第7/8/9步。
接下来具体分析每一步的过程
1. 向集群服务器发送投票sendNotifications()
2. 如果未收到任何选票则重新发送投票
3. 对方服务器在选举中LOOKING
前面我们介绍Vote类的时候提到过投票PK,从选举轮次epoch、ZXID和SID三个因素来考虑
- 首先比较选举轮次epoch,如果外部投票的选举轮次低于内部投票则丢弃外部投票,如第2步
- 如果外部投票的选举轮次高于内部投票,则更新内部选举轮次,然后再继续PK投票决定是否更新内部推举的leader信息,如第1步
- 一致的话直接PK投票,如第3步
投票PK结束后进行汇总,如第4步
统计投票,如第5/6步
投票统计结束后,如果此时已经产生leader,则更新当前服务器装填,如第10步。
源码过程如下:
4. 对方服务器是learner
5. 对方服务器是Leader
至此,选举的模块介绍到此结束,当Leader选举结束后各个服务器的角色也确定,接下来就是各种服务器角色的初始化工作,未完待续。