在Zookeeper集群正常运行期间,一旦选举出Leader,所有服务器的集群状态一般不会发生改变,即使是新机器加入、非Leader机器挂了,也不会影响Leader。但是一旦Leader挂了,那么整个集群将暂时无法对外服务,而是进入新的一轮Leader选举。服务器运行期间的Leader选举和服务器启动期间的Leader选举基本过程是一致的。
在服务器启动期间,如果超过2台机器启动了,那么这些机器会尝试去选举出一个Leader。Leader用于处理客户端请求。
Leader选举的隐式条件是至少要有2台服务器。
下面我们假设当前有Server1、Server2、Server3 三台机器为例子。在服务器集群初始化节点,有一台机器(假设这台机器myId=1,我们称他为Server1)启动的时候,那么1台机器是无法进行选举的。当第二台机器(myId=2,称为Server2)启动的时候,两台机器试图找出一个Leader,因此进入Leader选举流程,如下:
我们假设正在运行的Zookeeper集群由3台机器组成,分别为Server1、Server2、Server3。当前Leader是Server2。假设某一瞬间,Leader挂了,那么开始Leader选举:
首选介绍一些专业术语
SID:服务器ID。是一个数字,用来唯一标识Zookeeper集群中的一台机器。
ZXID:事务ID。用来唯一标识一次服务器状态变更。在某一时刻,集群中每台机器的ZXID值不一定完全一致。
Vote:投票。通过投票选出Leader。为(myId,ZXID)的形式
Quorum:指Zookeeper集群中过半的机器数。如果集群总机器数是n,那么quorum=(2/n)+ 1;
下面开始算法分析:
当Zookeeper集群中一台服务器出现下面2种情况之一时,就会进入Leader选举:
当一台机器进入Leader选举流程时,当前集群也可能处于以下2种状态:
当集群中不存在Leader的时候,所有机器都试图去寻找一个Leader,这种寻找Leader的状态称为“LOCKING”。
当一台机器处于LOCKING状态,它就会向其他机器发送消息,我们称这个消息为“投票”。
这个投票消息中包含了2个最基本的信息:所推举的服务器的SID和ZXID,分别代表了被推举服务器的唯一标识和事务ID。
集群中每台机器发出投票之后,也会收到其他机器发来的投票。每台机器会根据规则,处理其他机器的投票,并以此决定是否需要变更自己的投票。(变更规则在《概述》里面讲了。)
然后把投票再一次发出去。
经过第二次投票以后,集群中所有机器收到其他机器的投票,然后开始统计投票。如果一台机器收到过半的投票,那么该机器就称为Leader。
简单来说,哪台机器上的数据越新,越有可能成为Leader。原因很简单,数据越新,那么该机器的ZXID越大,越能够保证数据的恢复,不丢失。
本节讲述FastLeaderElection的实现。
LOOKING:寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举流程。
FOLLOWING:跟随者状态。表明当前服务器的状态是跟随者(Follower)
LEADING:领导者状态。表明当前服务器是领导者。
Observing:观察者状态,表明当前服务器是观察者
在Leader选举过程中,QuorumCnxManager负责各个机器之间的网络通讯。
QuorumCnxManager内部维护了一个消息队列。用于保存接收到的、待发送的消息。除了接收队列以外,所有队列都按SID分组形成队列集合。举个例子,假设集群中除了当前机器以外,还有4台机器,那么就会为这4台机器分别创建一个发送队列,互不干扰。
为了能够互相投票,Zookeeper集群中所有机器都必须要两两建立起网络连接。QuorumCnxManager启动的时候,会去监听Leader选举的通讯端口。为了避免2台机器之间重复建立TCP连接,Zookeeper规定2台机器之间,只有SID大的机器能够主动发起连接,否则断开连接。如果当前服务器发送自己的SID更大,那么就会断开当前连接,然后主动去和其他服务器连接。
###FastLeaderElection
FastLeaderElection是选举算法的核心部分,首先我们约定几个概念:
https://blog.csdn.net/weixin_41098980/article/details/80109789
《Paxos到Zookeeper 分布式一致性原理与实践》