文章目录

  • Zookeeper 选举相关源码
  • 一、选举阅读前了解
  • 1、选举相关参数
  • a、服务器ID(myid)
  • b、zxid事务ID
  • c、逻辑始终(epoch-logicalclock)
  • d、选举状态
  • 二、选举逻辑
  • 1、服务启动时的 leader 选举
  • 2、运行过程中的选举
  • 三、选举相关源码
  • 1、Leader选举的源码分析
  • 2、zkServer 服务启动逻辑
  • 3、选举流程分析
  • 4、投票的网络通信流程
  • 5、选举完成之后的处理逻辑


Zookeeper 选举相关源码

准备:

生产者/消费者的多线程模型

责任链设计模式

zk 4.4.14 版本

一、选举阅读前了解

再分析源码之前,先了解整个过程

leader 选举存在与两个阶段中,

一个是服务器启动时的leader 选举。

另一个是运行过程中leader 节点宕机导致的leader选举

1、选举相关参数
a、服务器ID(myid)

集群中每台服务器都有独一无二的编号,编号越大再选择算法中的权重越大

b、zxid事务ID

值越大说明数据越新,再选举算法中的权重也越大

c、逻辑始终(epoch-logicalclock)

或者叫投票的次数,同一轮投票过程中的逻辑始终值是相同的。每投完一次票这个数据就会增加,然后与其它服务器返回的投票信息中的数据相比,根据不同的值做出不同的判定。

d、选举状态
  • LOOKING,竞选状态
  • FOLLOWER ,随从状态,同步leader 状态,参与投票
  • OBSERVING,观察状态,同步leader 状态,不参与投票
  • LEADING,领导者状态

二、选举逻辑

1、服务启动时的 leader 选举

每个节点启动的时候状态都是LOOKKING,处于观望状态,接下来就开始进行选主流程

若进行 Leader 选举,则至少需要两台机器,这里选取 3 台机器组成的服务器集群为例。再集群初始化阶段,当有一台服务器server1 启动时,其单无法进行和完成选举,当第二台服务器 server2 启动时,此时两台机器可以进行通信,每台机器都试图找到 Leader,于是进入 Leader 选举过程。选举过程如下:

(1)、每个 Server 发出一个投票。由于是初始情况,Server1 和 Server2 都会将自己作为Leader 服务器来进行投票,每次投票会包含所推举的服务器的 myid 和 ZXID、epoch,使用(myid、ZXID、epoch)来表示,此时 Server1 的投票为(1,0),Server2 的投票为(2,0),然后各自将这个投票发给集群中其他机器。

(2)、接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自LOOKING 状态的服务器。

(3)、处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行 PK,PK 规则如下

  • 优先epoch
  • 其次检查ZXID。ZXID 比较大的服务器优先作为Leader
  • 如果ZXID 相同,那么就比较 myid。myid 较大的服务器作为 Leader 服务器。
  • 所以对于Servier1 而言,它的投票是(1,0),接受Server2的投票为(2,0),首先会比较两者的ZXID,均为0,再比较myid,此时Server2 的myid 最大,于是更新自己的投票为(2,0),然后重新投票,对于Server2 而言,其无需更新自己的投票,只是再次向集群中所有机器发出一次投票信息即可。

(4)、统计投票。每次投票 后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息。对于Server1、Server2而言,都统计出集群中已经有两台机器接受(2,0)的投票信息,此时便认为已经选出了Leader。

(5)、改变服务器状态。一旦确定了 Leader,每个服务器就会更新自己的状态,如果是 Follower ,那么就变更为 FOLLOWER,如果是 Leader ,就变更为Leader

2、运行过程中的选举

当集群中的 Leader 服务器出现宏机或者不可用的情况时,那么整个集群将无法对外提供服务,而是进入新一轮的 Leader 选举,服务器运行期间的 Leader 选举和启动期间的 Leader 选举基本过程是一致的。

(1)、变更状态。 Leader 挂了后,余下的非 Observer 服务器都会将自己的服务器状态更为LOOKING,然后进入 Leader 选举过程。

(2)、每个Server会发出一个投票。在运行期间,每个服务器上的ZXID 可能不同,此时假定 Server1的ZXID 为123, Server3 的ZXID 为 122; 在第一轮投票中,Server1 和 Server3 都会投自己,产生投票(1,123),(3,122),然后各自将投票发送给集群中所有机器。接收来自各个服务器的投票。与启动时过程相同。

(3)、处理投票。与启动是过程相同,此时,Server1 将会成为 Leader/

(4)、统计投票。与启动时过程相同。

(5)、改变服务器的状态**。与启动时过程相同

三、选举相关源码

有兴趣的朋友可以看看, 里面基本就是把通讯逻辑弄好了就ok了,采用的是消费者/生产者模型

已翻译了的Zookeeper源码地址:https://gitee.com/kylin1991_admin/zookeeper/tree/branch-3.4.14/

相关流程图:http://assets.processon.com/chart_image/5ea0c6cde0b34d05e1a5a16c.png

1、Leader选举的源码分析


QuorumPeerMain QuorumPeer FasstLeaderElection Messenger mian()方法 rumFromConfig() QuorumPeer.start() 进入线程的start()方法 startLeade rElection() createElecti onAlgorithm() 构建选举算法 starter() 构建Messenge() WorkerSender 线程 WorkerReceiver线程 QuorumPeerMain QuorumPeer FasstLeaderElection Messenger 选举的源码分析


2、zkServer 服务启动逻辑


QuorumPeerMain QuorumPeer QuorumPeerMain mian()方法 rumFromConfig() ServerCnxnFactor y.createFactory() cnxnFactory .configure() quorumPeer.start() 进入相关启动 start() cnxnFactory.start() QuorumPeerMain QuorumPeer QuorumPeerMain 服务启动逻辑


3、选举流程分析


QuorumPeer FastLeaderElection QuorumMaj run()方法 FastLeaderElectio n.lookForLeader() 进入选举 termPredic at()判断是否结束 是否可以选出Leader containsQuorum() 选举算法 QuorumPeer FastLeaderElection QuorumMaj 选举流程分析


4、投票的网络通信流程


FastLeaderElection QuorumCnxManager QuorumCnxMan lookForLeader()方 法 sendqueue() 调用toSend() toSend() startConnection() run() 调用receiveConnection()) handleCon nection() FastLeaderElection QuorumCnxManager QuorumCnxMan 投票的网络通信流程


5、选举完成之后的处理逻辑

没说明说的,就是

FOLLOWER:makeFollower() 然后 followLeader()

LEADER:makerLeader 然后 lead()