ZooKeeper集群中的三种服务器角色:Leader、Follower和 Observer。
ZXID:事务ID
ZXID是一个事务ID,用来唯一标识一次服务器状态的变更。在某一个时刻,集群中每台机器的ZXID值不一定全都一致,这和ZooKeeper服务器对于客户端“更新请求”的处理逻辑有关。
服务器启动时期的Leader选举
- 隐式条件便是ZooKeeper的集群规模至少是2台机器。最好是单数台,例如3台。
当有一台服务器,我们假设这台机器的myid为1,启动的时候,是无法进行Leader选举的。当第二台机器,假设这台服务器的myid为2,也启动后,此时这两台机器已经能够进行互相通信,每台机器都试图找到一个Leader,于是便进入了Leader选举流程。
Leader选举
- 每个Server会发出一个投票。
由于是初始情况,myid1和myid2来说,都会投自己为Leader,每次投票包含的最基本的元素包括:所推举的服务器的 myid 和ZXID,我们以(myid,ZXID)的形式来表示。即myid1的投票数据内容为(1,0),myid2的投票内容为(2,0),将这个投票发给集群中其他机器。 - 接收来自各个服务器的投票。
每个服务器都会接收来自其他服务器的投票。集群中的每个服务器在接收到投票后,首先会判断该投票的有效性,包括检查是否是本轮投票、是否来自LOOKING状态的服务器(处在投票中的机器)。 - 处理投票
接收到来自其他服务器的投票后,针对每一个投票,服务器将别人的的投票和自己的投票进行PK。
. 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
· 如果ZXID相同的话,那么就比较myid。myid比较大的服务器作为Leader服务器。
现在我们来看Server1和Server2实际是如何进行投票处理的。对于Server1来说,它自己的投票是(1,0),而接收到的投票为(2,0)。首先会对比两者的ZXID,因为都是0,所以无法决定谁是Leader。接下来会对比两者的myid,很显然,myid1发现接收到的投票中的myid是2,大于自己,于是就会更新自己的投票为(2,0),然后重新将投票发出去。而对于myid2来说,不需要更新自己的投票信息,只是再一次向集群中所有机器发出上一次投票信息即可。 - 统计投票
每次投票后,服务器都会统计所有投票,判断是否已经有过半的机器接收到相同的投票信息。对于myid1和myid2服务器来说,都统计出集群中已经有两台机器接受了(2,0)这个投票信息。对于这里由3台机器构成的集群,大于等于2台即为达到“过半”要求。那么,当myid1和myid2都收到相同的投票信息(2,0)的时候,即认为已经选出了Leader。 - 改变服务器状态。
一旦确定了 Leader,每个服务器就会更新自己的状态:如果是 Follower,那么就变更为FOLLOWING,如果是Leader,那么就变更为LEADING。
服务器运行期间的Leader选举
一旦选出一个Leader,Leader服务器将一直作为集群的Leader,即使集群中有非Leader机器挂了或是有新机器加入集群也不会改变Leader。只有Leader所在的机器挂了,进入新一轮的Leader选举。并且整个集群将暂时无法对外服务。
- 变更状态
当 Leader 挂了之后,余下的Follower服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举流程。 - 每个Follower会发出一个投票。
在这个过程中,需要生成投票信息(myid,ZXID)。运行期间,因此每个Follower服务器上的ZXID可能不同,在第一轮投票中,myid1和 myid3都会投自己,即分别产生投票(1,x)和(3,y),(x,y为各自的ZXID),各自将这个投票发给集群中所有机器。 - 接收来自各个服务器的投票。
- 处理投票。
比对两台机器的ZXID的大小,ZXID小的机器于是就会更新自己的投票为,然后重新将投票发出去。而对于大的机器来说,不需要更新自己的投票信息,只是再一次向集群中所有机器发出上一次投票信息即可。 - 统计投票(服务器启动时期的Leader选举一致)
- 改变服务器状态(服务器启动时期的Leader选举一致)
在ZooKeeper中,提供了三种Leader选举的算法,
- LeaderElection
- UDP版本的FastLeaderElection
- TCP版本的FastLeaderElection
可以在配置文件zoo.cfg中使用electionAlg属性来指定,分别使用数字0~3来表示。
- 0代表LeaderElection,这是一种纯UDP实现的Leader选举算法;
- 1代表UDP版本的FastLeaderElection,并且是非授权模式;
- 2 也代表 UDP 版本的 FastLeaderElection,但使用授权模式;
- 3 代表 TCP版本的FastLeaderElection。
从3.4.0版本开始,ZooKeeper废弃了0、1和2这三种Leader选举算法,只保留了TCP版本的FastLeaderElection选举算法。