ZooKeeper | leader选举

609 阅读4分钟

1. ZooKeeper Leader选举

1.1 概述

leader选举是保证分布式数据一致性的关键所在。leader选举包括ZK集群启动时选举和集群运行期间重新选举两种情况。

1.2 ZK基本概念说明

1.2.1 ZK节点状态

  1. LOOKING:寻找leader状态,处于该状态需要进入选举流程
  2. LEADING:领导者状态,处于该状态说明该节点是leader
  3. FOLLOWING:跟随者状态,处于该状态说明集群已经完成leader选举,该节点是follower状态
  4. OBSERVER:观察者状态,标识该节点是observer

1.2.2 事务ID

zookeeper状态的每次变化都接收一个ZXID(zk的事务ID),ZXID是一个64位的数字,由leader统一分配,全局唯一,不断递增。

ZXID展示了Zookeeper的所有变更顺序,如果zxid1小于zxid2,说明zxid1在zxid2之前发生。

1.2.3 leader选举算法

zk的领导选举算法可以通过electionAlg配置项进行设置,截止到3.4.10版本,提供的选举算法如下:

  • 基于UDP的LeaderElection
  • 基于UDP的FastLeaderElection
  • 基于UDP和认证的FastLeaderElection
  • 基于TCP的FastLeaderElection

在3.4.10中,默认使用的是3(基于TCP的FastLeaderElection),其他几种算法已经被弃用。FastLeaderElection是Fast Paxos算法的实现,能够解决LeaderElection选举算法收敛速度慢的问题。

1.2.4 选票数据结构

每个节点在leader选举时,会发送如下关键信息:

  1. logicClock:每个节点会维护一个自增的数字,表示这是该节点发起的第几轮投票
  2. state:当前节点的状态
  3. self_id:当前节点的myid
  4. self_zxid:当前节点的最大zxid
  5. vote_id:被选举节点的myid
  6. vote_zxid:被选举节点的最大zxid

1.3 ZK初始化时leader选举

以3台机器的集群为例。在集群初始化阶段。当有一台服务器ZK1启动时,其单独无法进行和完成选举,当第2个服务器启动时,此时2个服务器可以通信,都试图找到leader,于是进入leader选举过程,如下:

  1. 每个节点发出一个投票,由于是初始化状态,zk1和zk2都将自己作为leader服务器进行投票,投票信息包含myid和zxid,使用(myid,zxid)标识,zk1的投票信息为(1,0),zk2的投票信息为(2,0),然后将投票信息发送给集群中的其他节点;

  2. 集群中每个节点接收到投票后,判断投票是否有效,如:是否本轮投票、是否来自looking状态的服务器

  3. 处理投票。针对每一个投票,节点都需要将别人的投票和自己的投票比较,规则如下:

    • 优先检查zxid,zxid大的优先作为leader
    • 如果zxid相同,则比较myid大小,myid大的优先作为leader

    对于zk1而言,他的投票是(1,0),zk2的投票为(2,0),首先比较2者的zxid,是一致的;然后比较myid,zk2的大,则zk1更新自己的投票为(2,0),并将投标结果发送给zk2

  4. 统计投票。每次投票后,都会统计投票信息,判断是否有过半节点接收到相同的投票信息。对于zk1和zk2而言,统计出集群中已经有2个(2,0)的投票信息,此次便认为zk2为leader。

  5. 修改节点状态。一旦确定了leader,每个节点都会修改自己的状态。如果是follower则修改为FOLLOWING,如果是leader,则修改为LEADING。当信息的节点zk3启动时发现已经有leader,则自动从LOOKING状态变为FOLLOWING。

1.4 ZK运行期间leader选举

在ZK运行期间,如果leader节点挂了,则整个集群暂停对外服务,进入leader选举

假设正在运行的有3个节点,分别是zk1,zk2,zk3,其中zk2是leader。leader节点挂了后进入leader选举,过程如下:

  1. 变更状态。leader挂后,所有的非observer节点状态都会变为looking,然后进入leader选举
  2. 每个节点发出一个投票。在运行期间,每个节点zxid可能不同,假定zk1的zxid为100,zk3的zxid为99。在第一轮投标中,zk1和zk3都会投票为自己,则投票信息为(1,100)、(3,99),然后将投票信息发送给集群中的其他节点。
  3. 接收来个各个节点的投票,与启动过程类似。
  4. 处理投标,与启动过程类似。
  5. 统计投票,与启动过程类似。
  6. 修改节点状态,与启动过程类似。

参考

Zookeeper的Leader选举哪些事