当前位置:   article > 正文

zookeeper 半数选举过程

zookeeper 半数选举过程

前言

在讲解流程之前,先说明一下选举流程中涉及到的角色,以及涉及到的关键类和变量(源码参考版本:3.4.9):

要半数以上的机器投票自己,自己才能是leader。若是4台则必须 是3台投自己。

怎么算机器总数,是在配置文件中配置的节点数(即使其中某几个没有启动)

角色:1.LOOKING:竞选

           2.OBSERVING:观察

           3.FOLLOWING:跟随者

           4.LEADER:领导者

投票信息:

           1.logicalclock(electionEpoch):本地选举周期,每次投票都会自增

           2.epoch(peerEpoch):选举周期,每次选举最终确定完leader结束选举流程时会自增(真正zxid的前32位)

           3.zxid:数据事务ID,每次数据变动都会自增(真正zxid的后32位,zxid一共64位)

           4.sid:该投票信息所属的serverId,即配置的myid文件中的值

           5.leader:提议的leader(被提议的server的serverId,即sid)

投票比较规则:

          1.logicalclock 大的胜出,否则进行步骤2

          2.zxid大的胜出,否则进行步骤3

          3.sid大的胜出
 

 

 

 

FastLeaderElection:选举算法核心

  · 外部投票:特指其他服务器发来的投票。

  · 内部投票:服务器自身当前的投票。

  · 选举轮次Zookeeper服务器Leader选举的轮次,即logicalclock。

  · PK:对内部投票和外部投票进行对比来确定是否需要变更内部投票。

  (1) 选票管理

  · sendqueue:选票发送队列,用于保存待发送的选票。

  · recvqueue:选票接收队列,用于保存接收到的外部投票。

  · WorkerReceiver:选票接收器。其会不断地从QuorumCnxManager中获取其他服务器发来的选举消息,并将其转换成一个选票,然后保存到recvqueue中,在选票接收过程中,如果发现该外部选票的选举轮次小于当前服务器的,那么忽略该外部投票,同时立即发送自己的内部投票。

  · WorkerSender:选票发送器,不断地从sendqueue中获取待发送的选票,并将其传递到底层QuorumCnxManager中。

  (2) 算法核心

  上图展示了FastLeaderElection模块是如何与底层网络I/O进行交互的。Leader选举的基本流程如下

  1. 自增选举轮次。Zookeeper规定所有有效的投票都必须在同一轮次中,在开始新一轮投票时,会首先对logicalclock进行自增操作。

  2. 初始化选票。在开始进行新一轮投票之前,每个服务器都会初始化自身的选票,并且在初始化阶段,每台服务器都会将自己推举为Leader。

  3. 发送初始化选票。完成选票的初始化后,服务器就会发起第一次投票。Zookeeper会将刚刚初始化好的选票放入sendqueue中,由发送器WorkerSender负责发送出去。

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

  5. 判断选举轮次。在发送完初始化选票之后,接着开始处理外部投票。在处理外部投票时,会根据选举轮次来进行不同的处理。

    · 外部投票的选举轮次大于内部投票。若服务器自身的选举轮次落后于该外部投票对应服务器的选举轮次,那么就会立即更新自己的选举轮次(logicalclock),并且清空所有已经收到的投票箱,然后使用初始化的投票来进行PK以确定是否变更内部投票。最终再将内部投票发送出去。

    · 外部投票的选举轮次小于内部投。若服务器接收的外选票的选举轮次落后于自身的选举轮次,那么Zookeeper就会直接忽略该外部投票,不做任何处理,并返回步骤4。

    · 外部投票的选举轮次等于内部投票。此时可以开始进行选票PK。

  6. 选票PK。在进行选票PK时,符合任意一个条件就需要变更投票。

    · 若外部投票中推举的Leader服务器的选举轮次大于内部投票,那么需要变更投票。

    · 若选举轮次一致,那么就对比两者的ZXID,若外部投票的ZXID大,那么需要变更投票。

    · 若两者的ZXID一致,那么就对比两者的SID,若外部投票的SID大,那么就需要变更投票。

  7. 变更投票。经过PK后,若确定了外部投票优于内部投票,那么就变更投票,即使用外部投票的选票信息来覆盖内部投票,变更完成后,再次将这个变更后的内部投票发送出去。

  8. 选票归档。无论是否变更了投票,都会将刚刚收到的那份外部投票放入选票集合recvset中进行归档。recvset用于记录当前服务器在本轮次的Leader选举中收到的所有外部投票(按照服务队的SID区别,如{(1, vote1), (2, vote2)...})。

  9. 统计投票。完成选票归档后,就可以开始统计投票,统计投票是为了统计集群中是否已经有过半的服务器认可了当前的内部投票,如果确定已经有过半服务器认可了该投票,则终止投票。否则返回步骤4。

  10. 更新服务器状态。若已经确定可以终止投票,那么就开始更新服务器状态,服务器首选判断当前被过半服务器认可的投票所对应的Leader服务器是否是自己,若是自己,则将自己的服务器状态更新为LEADING,然后广播出去,若不是,则根据具体情况来确定自己是FOLLOWING或是OBSERVING。

  以上10个步骤就是FastLeaderElection的核心,其中步骤4-9会经过几轮循环,直到有Leader选举产生。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/952610
推荐阅读
相关标签
  

闽ICP备14008679号