龙空技术网

入门Zookeeper-Zookeeper选主算法分析?

从程序员到架构师 85

前言:

现在姐妹们对“算法设计主方法”大致比较注重,我们都需要学习一些“算法设计主方法”的相关内容。那么小编也在网上汇集了一些对于“算法设计主方法””的相关文章,希望同学们能喜欢,咱们快快来学习一下吧!

在上篇文章中,我们介绍了关于Zookeeper的选择Leader的过程,下面我们就来介绍一下在Zookeeper中用到的Leader选举算法。

Zookeeper中用到的Leader选举算法有如下三种

LeaderElection基于UDP的FastLeaderElection基于TCP的FastLeaderElection

可以通过zoo.cfg中通过electionAlg属性来进行配置。但是在高版本的Zookeeper中只保留了基于TCP的FastLeaderElection。下面我们就详细介绍一下基于TCP的FastLeaderElection算法。

算法分析

首先根据上篇文章中我们提到的,Zookeeper集群的服务器出现如下两种情况的时候就会触发Leader的选举。

服务器开始初始化完成,开始进入到Leader的选择当服务器中已经存在的Leader节点出现了宕机的情况

而一个服务器在进入到Leader选举流程的时候,也会存在两种情况。

服务器集群中已经存在了一个Leader节点,进入之后会成为Follower节点。集群中还没有选择出来Leader节点,也就是集群中的节点刚刚开始恢复,或者是启动。

首先第一种情况说明,当该节点启动的时候,服务器集群中的其他节点已经在正常的运行了,并且在这个集群中存在一台正常运行中的Leader服务器,针对这种情况,基本上当该机器进入之后,会立即进行Leader的选举,然后就被集群通信告知,已经存在了Leader节点,这个时候这个机器只需要与Leader建立通信,并且同步相关状态即可。

但是如果不存在Leader节点的话,可能是由于两个原因导致,一种是集群节点刚刚启动,还没有来得及选择出Leader。而另一种则是正常运行的Leader节点突然挂机了。但是无论是什么情况导致的,这个时候集群中的节点就会立即决定选出一个Leader节点,这个时候,所有的服务器都会进入到了一个LOOKING的状态,也就是告诉其他节点要开始选Leader了,这个时候所有的服务器就会开始向其他机器发送消息,这个消息,在上篇文章中我们称之为“投票”

在上篇介绍中,我们知道这个消息中包含了两个基本的信息,一个是服务器的ID,一个是ZXID。分别表示被推举的服务器的唯一标识ID和事务的ID,可以通过(SID,ZXID)这种方式来表示。

例如当前参与选举的Server1服务器对应的SID为123,其对应的ZXID为456,它的投票信息就可以表示为(123,456)。

假设集群中有五台服务器分别是Server1(1,7)、Server2(2,7),Server3(3,7)、Server4(4,7)、Server5(5,8)

此刻,Leader为Server2,在某一时刻,Server2突然宕机了。这个时候集群就开始选主了。在第一次投票的时候,由于集群中的其他机器状态还无法被检测到,所以每台机器先给自己投了一票。这个时候投票情况就是Server1、Server3、Server4、Server5各自有一张选票。

按照之前的说法,在集群中的机器分别为自己投票之后,接下来就是要接收到其他机器的投票了。这个时候,每一台机器会根据规则来处理接收到的投票信息。这个规则就是Zookeeper选主算法的核心。规则如下

首先当服务器收到投票信息之后,第一个需要判断的是自己的ZXID与收到的ZXID的大小,如果收到的ZXID大于自己的ZXID,那么就直接将自己的选票改成对应的ZXID。然后将选票发送出去。如果自己的ZXID大于收到的ZXID,那么就坚持自己的选票,然后不做任何改变的将选票发送出去。如果收到的ZXID与自己的ZXID相等,那么就需要比较SID的大小了,如果收到的SID大于自己的SID,那么就修改自己的选票,然后将选票发送出去。如果在ZXID相同的情况下,自己的SID大于收到的SID,那么就保持自己的选票不变,然后将选票发送出去。

这个时候,会有人问出一个非常幼稚的问题,如果ZXID和SID都相等该怎么办?根据上面我们提到的,如果二者相等就说明是同一个机器,因为ZXID和SID不可能同时相等。

根据上面的规则,我们来看看上面的集群选主之后的结果。

对于Server3(3,7) 来讲,会收到三组投票,分别是(1,7)、(4,7)、(5,8)。经过上述条件比较之后,最终会得到(5,8)这个结果。对于Server1(1,7) 来讲,会收到三组投票,分别是(3,7)、(4,7)、(5,8)。经过上述条件比较之后,最终会得到(5,8)这个结果。对于Server4(4,7) 来讲,会收到三组投票,分别是(1,7)、(3,7)、(5,8)。经过上述条件比较之后,最终会得到(5,8)这个结果。对于Server5(5,8) 来讲,会收到三组投票,分别是(1,7)、(3,7)、(4,7)。经过上述条件比较之后,最终会得到(5,8)这个结果。

经过一轮投票之后,根据规则判断,有超过了一半以上的节点都是(5,8)这个选票。这个时候Server5最终就成了新的Leader节点。

总结

从上面的分析可以看出,一般情况下,那个机器上的节点数据越新,那么对应的节点越有可能被选择成为新的Leader。原因非常简单,就是数据越新的节点ZXID的值可能越大,这也就可以保证当它被选择为Leader节点之后,能够带领其他的节点使得数据达到最大程度的恢复。如果集群中存在ZXID相同的情况,那么SID最大的则可能成为Leader,这就要看服务器如何进行配置了。

标签: #算法设计主方法