通用组件之Zookeeper-FLE算法
zookeeper使用的默认选主算法是FastLeaderElection,可解决LeaderElection选举算法收敛速度慢的问题。
ZAB协议规定的状态:
LOOKING 当前集群没有leader,准备选举
FOLLOWING 已经存在leader,当前服务器为跟随者
LEADING 唯一的领导,维护与Follower间的心跳
OBSERVING 观察者状态。表明当前服务器角色是Observer
选举的大致流程如下:
投票的依据:
投票的依据就是下面的两个id,投票即是给所有服务器发送(zxid,myid)信息:zxid有64位,分成两部分:高32位是Leader的epoch:选举时钟,每次选出新的Leader,epoch累加1。低32位是在这轮epoch内的事务id:对于用户的每一次更新操作集群都会累加1。myid:用户在配置文件中自己配置,每个节点都要配置的一个唯一值,从1开始往后累加。
关于发送选票:
第一轮投给自己,之后每个服务器把上述所有信息发送给其他所有服务器,票箱中只会记录最后一轮投票结果
关于接收投票
服务器会尝试从其它服务器获取投票,并记入自己的投票箱内。如果无法获取任何外部投票,则会确认自己是否与集群中其它服务器保持着有效连接。如果是,则再次发送自己的投票;如果否,则马上与之建立连接。
关于选举轮次
由于所有有效的投票都必须在同一轮次中。每开始新一轮投票自身的logicClock自增1。接收到的logicClock大于自己的。说明自己落后了,更新logicClock后清空票箱继续投票。接收到的logicClock小于自己的。忽略该票继续投票。接收到的logickClock与自己的相等,正常判断。
关于选票判断
对比自身的和接收到的(myid,zxid),首先对比zxid高32位的选举时钟epoch,一致则对比zxid低32的事务id,仍然一致则对比用户自己配置的myid。永远选择较大的。选完后广播选出的(myid,zxid)。过半服务器选了同一个,则投票结束,根据投票结果更新自身状态为leader或者follower
选举完成之后的各个不同状态的数据同步
对比leader的LastCommitttedZxid与follower的LastZxid,如果follower比较大,说明follower中存在应该丢弃的proposal。如果leader比较大,则会拿一个很陈旧的oldThreshold与leader进行比较,如果leader比较大,说明follower是刚刚加入集群的,则直接复制全量数据,否则直接提交所有的proposal,更新至与leader一致的状态,然后需要确保所有的Follower服务器能够接收到每一条事务的Proposal,之后才会把该Follower加入到真正可用的Follower列表中。