Leader选举是保证分布式数据一致性的关键所在,Leader的选举发生的情况有两种:一种是服务器启动时选举,另一种是运行期间Leader宕掉或与Leader保持连接的机器少于一半,这时会进行重新选Leader。
1.首先是服务器启动时选举Leader,若进行Leader的选举的话,则至少需要2台机器,这里选3台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器Server1启动时,其无法单独进行完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以互相通信,每台机器都试图找到Leader,于是就进入Leader选举的过程。过程如下:
(1)每个服务器会生成一个选票,因为是初始情况,所以Server1和Server2都会选自己作为Leader服务器来进行投票,每次选票都会包含所推举的服务器的myid和ZXID,用(myid,ZXID)来表示选票,此时Server1的投票为(1,0),Server2的投票为(2,0),然后各自将这个投票发送给集群中的其他机器。
(2)各个Server接收到了来自其他服务器的投票后,首先判断这个投票是否有效,如检查是否是本轮投票、是否来自LOOKING状态的服务器(observer)。
(3)检查完成后,其他投票有效的话,服务器就会针对每一个投票跟自己的选票进行PK,PK规则如下:
·优先比较两个的ZXID,ZXID大的服务器优先作为Leader
·如果ZXID相同,那就比较myid,选myid较大的服务器作为Leader服务器
这里对于Server1和Server2来说,首先比较他们两个的ZXID,因为他们的ZXID相同都是0,所以就比较他们的myid,因为Server2的myid为2并且大于Server1的myid,所以选Server2为Leader。接着Server1更新自己的选票为(2,0),然后重新投票。对于Server2来说,不需要更新自己的投票,只是再次向集群中所有机器发送一次自己的选票。
(4)每次投票之后,服务器都会统计投票信息,判断是否已经有过半的机器接收了相同的投票信息,对于Server1和Server2来说,都统计出集群中已经有两台机器接受了(2,0)的投票信息,此时便认为已经选出了Leader。
(5)一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follow,状态变为FOLLOWING,如果是Leader,状态变为LEADING。
在ZAB协议的设计中,每一个进程都有可能处于以下三种状态之一:
LOOKING:Leader选举阶段
FOLLOWING:Follower服务器和Leader保持同步状态
LEADING:Leader服务器作为主进程领导状态
2.其次是运行期间Leader宕掉或与Leader保持连接的服务器少于一半
在ZooKeeper运行期间,Leader与非Leader服务器各司其职,即便有非Leader服务器宕掉或新加入,也不会影响Leader。但一旦Leader服务器挂掉,那整个集群就将暂停对我服务,进入新一轮的Leader选举,选举过程和启动时期的Leader选举过程基本一致。假设正在运行的服务器有Server1、Server2、Server3,当前Leader为Server2,若某一时刻Leader挂掉,便开始Leader选举。选举过程如下:
(1)变更状态:Leader挂掉后,剩下的非observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程。
(2)每个Server会发出一个投票,在运行期间,每个服务器上的ZXID可能不同,此时假定Server1的ZXID为123,Server3的ZXID为122;在第一轮投票中,Server1和Server3都会投自己,产生(1,123)、(3,122)的选票,然后各自将投票发送给集群中所有的机器。
(3) 接收来自各个服务器的投票。与启动时过程相同。
(4) 处理投票。与启动时过程相同,此时,Server1 将会成为 Leader。
(5) 统计投票。与启动时过程相同。
(6) 改变服务器的状态。与启动时过程相同。