Zookeeper的Leader选举

本文详细介绍了Zookeeper中Leader选举的过程,包括服务器启动时及运行期间的选举流程,并深入分析了选举算法及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

1.服务器启动时期的Leader选举。

若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例。在集群处理阶段,当有一台服务器Server1启动时,其单独无法进行和完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。

(1)每个Server发出一个投票。由于初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid,ZXID)来表示,此时Server1的投票为(1,0),Server2的投票为(2,0)然后各自将这个投票发送给集群中其他机器。

(2)接受来自各个服务的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票,是否来自LOOKING状态的服务器。

(3)处理投票。

  • 优先检查ZXID。ZXID比较大的服务器作为Leader。
  • 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。

对于Server1,由于Server2的myid最大,于是更新自己的投票为(2,0),然而后重新投票。

(4)统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受相同的投标信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2,0)的投票信息,此时便认为已经选出了Leader。

(5)改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态。

 

2.服务器运行期间的Leader选举

(1)变更状态,Leader挂后,余下的非Observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进和Leader选举过程。

(2)每个Server会发出一个投票,在运行期间,每个服务器上的ZXID可能不同,此时假设Server1的ZXID为123,Server3的ZXID为122

(3)接收来自各个服务器的投票

(4)处理投票,Server1将夫成为Leader。

(5)统计投票。

(6)改变服务器的状态。

 

Leader选举算法分析

在3.4.0后的Zookeeper中,只保留了TCP版本的FastLeaderElection选举算法。对于集群中已经存在Leader而言,此种情况一般都是某台机器启动行较晚,在其启动之前,集群已经在正常工作,对这种情况,该机器去选举Leader时,会被告知当前服务器的Leader信息,对于该机器而言,仅仅需要和Leader建立起连接,并进行状态同步即可。

 

Leader选举实现细节

1.投票数据结构

  • id:被推举的Leader的SID
  • zxid:被推举的Leader的事务ID
  • electionEpoch:逻辑时钟,用来判断多个投票是否在同一轮选举周期中,该值在服务端是一个自增序列,每次进入新一轮的投票后,都会对该值进行加1操作。
  • peerEpoch:被推举的Leader的epoch。
  • state:当前服务器的状态。

2.QuorumCnxManager:网络IO

每台服务器在启动的过程中,会启动一个QuorumCnxManager,负责各台服务器之间的底层Leader选举过程中的网络通信。

(1)消息队列。QuorumCnxManager内部维护了一系列的队列,除接收队列以外,其他队列都按照SID分组形成队列集合。

  • recvQueue:消息接收队列,用于存放那些从其他服务器接收到的消息。
  • queueSendMap:消息发送队列,用于保存那些待发送的消息,按SID进行分组。
  • senderWorkerMap:发送器集合,每个SenderWorker消息发送器,都对应一台远程Zookeeper服务器,负责消息的发送,也按照SID进行分组。
  • lastMessageSent:最近发送过的消息,为每个SID保留最近发送地的一个消息。

(2)建立连接。为了能够相互投票,Zookeeper集群中的所有机器都需要两两建立起网络连接。QuorumCnxManager在启动时会创建一个ServerSocket来监听Leader选举的通信端口(默认3888)。开启监听后,Zookeeper能够不断地接收来自其他服务器的创建连接请求,为了避免两台机器之间重复地创建TCP连接,Zookeeper只允许SID大的服务器主动和其他机器建立连接,否则断开连接。一旦连接建立,就会根据远程服务器的SID来创建相应的消息发送器SendWorker和消息接收器RecvWorker,并启动。

 

(3)消息接收与发送。在SendWorker中,一旦Zookeeper发现针对当前服务器的消息发送队列为空,那么此时需要从lastMessageSent中取出一个最近发送过的消息来进行再次发送,这是为了解决接收方在消息接收前或者接收到消息后服务器挂了,导致消息未被正确处理。同时,Zookeeper能够保证接收方在处理消息时,会对重复消息进行正确的处理。

 

最后欢迎大家访问我的个人网站:1024s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值