Zookeeper选举机制
Zookeeper集群角色
Leader:
-
负责处理客户端发送的读、写事务请求。这里的事务请求可以理解这个请求具有事务的 ACID 特性。
-
同步写事务请求给其他节点,且需要保证事务的顺序性。
Follower:
-
负责处理客户端发送的读请求
-
转发写事务请求给 Leader。
-
参与 Leader 的选举。
Observer:
-
和 Follower 一样,唯一不同的是,不参与 Leader 的选举,且状态为 OBSERING。
-
如果需要将哪一个节点设置为observer,那么只需要修改这个节点对应的zoo.cfg即可。
Zookeeper节点的四种状态
在知道了 Zookeeper 中有三种角色后,我们可能会问: Zookeeper 是如何知道自己目前是什么角色的呢?
在 ZAB 协议中定义:通过自身的状态来区分自己的角色的,在运行期间各个进程可能出现以下四种状态之一:
-
Looking:不确定Leader状态,该状态下的服务器认为当前集群中没有Leader,会发起Leader选举
-
Following:跟随者状态,表明当前服务器角色是Follower,并且它知道Leader是谁
-
Leading:领导者状态,表明当前服务器角色是Leader,它会维护与Follower间的心跳
-
Observing:观察者状态,表明当前服务器角色是Observer,与Follower唯一的不同在于不参与选举,也不参与集群写操作时的投票
在组成 ZAB 协议的所有进程启动的时候,初始化状态都是 LOOKING 状态,此时进程组中不存在 Leader,选举之后才有,在进行选举成功后,就进入消息广播模式,此时 Zookeeper 集群中的角色状态就不再是 LOOKING 状态。
启动阶段选举Leader
在Zookeeper集群中,当没有leader的时候,集群会自动进入选举状态(Looking) ,注意,此时所有的节点都会进入选举状态参与选举。
选举投票需要的信息
SID: 服务器ID, 作为当前Zk服务器,在集群中的唯一标识.
ZXID: 是一个用于标识ZooKeeper服务中发生的每一次状态变更的事务ID。每当ZooKeeper集群中的一个节点执行了一个写操作,如创建、更新或删除一个znode(ZooKeeper的数据节点),都会生成一个新的ZXID。 ZXID是分成两个部分的:高位用于表示epoch(用于区分选举轮次),而低位则是一个递增的计数器,用于在同一个epoch内保证事务的顺序性。
ZooKeeper集群在运行过程中可能会进行多次选举。每进行一次新的选举,epoch就会递增,这样就可以区分不同的选举轮次。这种机制确保了在选举过程中,只有最新一轮选举的结果才会被认为是有效的,避免了因网络延迟或其他原因导致的选票混淆。
启动阶段的投票流程
-
Zk01 节点先投票给自己,投票信息包括SID和ZXID,比如(1,0) . SID是配置好的,且唯一. ZXID是唯一的递增编号.
-
Zk02 先投票给自己,投票信息为 (2,0) .
-
Zk01和ZK02互相发送投票信息, 如果集群中还有其他节点,Zk01和Zk02会将自己的投票信息投给集群中的所有节点.
-
Zk01节点接收到Zk02节点的投票信息后,会检查节点Zk02的状态是否是本轮投票,以及是否是正在选举(Looking) 的状态(ZK02也会检查ZK01).
-
投票PK:这里节点 Zk01 和 Zk02 的 ZXID 相同,SID 的话,节点 Zk02要大些,所以节点 Zk01更新投票信息为(2,0),然后将投票信息再次发送出去。而节点 Zk02 不需要更新投票信息,但是下一轮还需要再次将投票发出去。
-
统计投票:每一轮投票,都会统计每台节点收到的投票信息,判断是否有过半的节点收到了相同的投票信息。节点 zk01 和 节点 zk02 收到的投票信息都为(2,0),且数量来说,大于一半节点的数量,所以将节点 B 选出来作为 Leader。
-
更新节点状态:节点 zk01 作为 Follower,更新状态为 FOLLOWING,节点 zk02 作为 Leader,更新状态为 LEADING。
注: 如果一个Zookeeper集群中已经存在了leader,那么此时新添一个或者多个节点,新添的节点的信息无论是什么样子,都只能成为follower。
非第一次启动时的选举过程
当zookeeper集群中的一台服务器,出现以下两种情况之一时,就会进入Leader选举:
-
情况1: 服务器初始化启动 (上面已经介绍了).
-
情况2: 服务器运行期间无法与Leader保持连接 (运行期间,Leader宕机了)
当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,ZAB 协议就会 进入崩溃恢复模式,选举产生新的 Leader。在 Zookeeper 运行期间,Leader 会一直保持为 LEADING 状态,直到 Leader 宕机了,这个时候就要重新选 Leader.
选举规则: epoch大的直接胜出 --> epoch相同,事务ID大的胜出 ----> 事务ID相同,服务器id大的胜出
注意:
-
observer状态不会发生改变,即一个节点如果设置为observer,那么这个节点从始至终都是observer状态。
-
Zookeeper中虽然存在leader和follower,但是这是两种状态,即任意一个节点都可以是leader,也都可能是follower,随时可能发生切换,所以Zookeeper不是严格意义上的主从结构!