ZooKeeper技术内幕——Leader选举

Leader选举的实现细节

服务器状态

  • LOOKING:寻找Leader状态,当服务器处于该状态的时候,它会认为当前集群中没有Leader,因此需要进入Leader选举流程
  • FOLLOWING:跟随者状态,表明当前服务器角色是Follower
  • LEADING:领导者状态,表明当前服务器角色是Leader
  • OBSERVING:观察者状态,表明当前服务器角色是Observer

投票数据结构

  • id:被推举的Leader的SID值,即myid中设置的参数
  • zxid:当前投票的事务ID
  • electionEpoch:逻辑时钟,每次进入新一轮的投票后,都会对该值进行加1操作,用来判断多个投票是否在同一轮选举周期中
  • peerEpoch:被推举的Leader的epoch
  • state:当前服务器的状态

消息队列

每台服务器启动的时候,都会启动一个QuorumCnxManager,负责各台服务器之间底层的Leader选举过程中的网络通信。

  • recvQueue:消息接收队列,用于存放那些从其他服务器接收到的消息
  • queueSendMap:消息发送队列,key(集群中其他机器的SID),value(消息内容)
  • senderWorkerMap:消息发送器集合,key对应SID,value对应每一台远程的ZooKeeper服务器
  • lastMessageSent:最近发送过的消息。在这个集合中,为每个SID保留最近发送过的一个消息

算法核心

1. 自增选举轮次

在FastLeaderElection实现中,有一个logicalclock属性,用于标识当前Leader的选举轮次,ZooKeeper规定了所有有效的投票都必须在同一轮次中。ZooKeeper在开始新一轮的投票时,会首先对logicallock进行自增操作

2. 初始化选票

初始化Vote数据结构

  • id:当前服务器自身的SID
  • zxid:当前服务器最新的ZXID值
  • electionEpoch:当前服务器的选举轮次
  • peerEpoch:被推举的服务器的选举轮次
  • state:LOOKING

3. 发送初始化选票

服务器发起第一次投票。ZooKeeper会将刚刚初始化的Vote放入sendqueue队列中,由发送器WorkerSender负责发送出去。

4. 接收外部选票

每台服务器会不断地从recvqueue队列中获取外部投票。如果服务器发现无法获取到任何的外部投票,那么就会立刻确认自己是否和集群中其他服务器保持有效连接;如果发现没有建立连接,就会建立连接,并再次发送自己当前的内部投票。

5. 判断选举轮次

根据选举的轮次处理外部投票

  • 外部投票的选举轮次大于内部投票
    更新自己的选举轮次(logicalclock),并且清空所有已经收到的选票,使用新初始化的投票与外部投票进行PK,最终再将内部投票发送出去

  • 外部投票的选举轮次小于内部投票
    ZooKeeper忽略该外部投票,返回步骤4

  • 外部投票的选举轮次与内部投票一致
    进行选票PK

注意,只有在同一选举轮次的投票才是有效的投票

6.  选票PK

  • 外部投票中被推举的Leader服务器的选举轮次大于内部投票,那么进行投票变更
  • 如果选举轮次一致,那么对比两者的ZXID,若外部投票的ZXID较大,进行投票变更
  • 如果两者的ZXID一致,那么就对比两者的SID,如果外部投票的SID较大,进行投票变更

7. 变更投票

通过选票PK之后,如果确定了外部投票优于内部投票(所谓的“优于”,是指外部投票所推举的服务器更适合成为Leader),那么进行投票变更——使用外部投票的选票信息来覆盖内部投票。变更完成之后,再次将这个变更的内部投票发送出去。

8. 选票归档

无论是否进行了投票变更,都会将刚刚收到的那份外部投票放入“选票集合”recvSet中进行归档,recvSet用于记录当前服务器在本轮次中的Leader选举中收到的所有外部投票——按照服务器对应的SID来区分,例如{(1, vote1), (2, vote2), …}

9. 统计投票

完成了选票归档之后,进行统计投票。如果确认已经有过半的服务器认可了该内部投票,则终止投票。否则返回步骤4。

10. 更新服务器状态

统计投票后,如果已经确定可以终止投票,那么就开始更新服务器状态。服务器首先判断当前被过半服务器认可的投票所对应的Leader服务器是否是自己,不过是自己的话,那么就会将自己的服务器状态更新为LEADING;否则,根据情况来确定自己是FOLLOWING或者是OBSERVING。

猜你喜欢

转载自blog.csdn.net/pierce_liu/article/details/80529010