ZooKeeper系统模型之集群版服务器启动过程。

        下图所示是集群版ZooKeeper服务器的启动流程图。

预启动

        预启动的步骤如下。

  • 统一由QuorumPeerMain作为启动类。
  • 解析配置文件zoo.cfg。
  • 创建并启动历史文件清理器DatadirCleanupManager。
  • 判断当前是集群模式还是单机模式的启动。

在集群模式中,由于已经在zoo.cfg中配置了多个服务器地址,因此此处选择集群模式启动ZooKeeper。

初始化

        初始化的步骤如下。

  • 创建ServerCnxnFactory。
  • 初始化ServerCnxnFactory。
  • 创建ZooKeeper数据管理器FileTxnSnapLog。
  • 创建QuorumPeer实例。

Quorum是集群模式下特有的对象,是ZooKeeper服务器实例(ZooKeeperServer)的托管者,从集群层面看,QuorumPeer代表了ZooKeeper集群中的一台机器。在运行期间,QuormPeer会不断检测当前服务器实例的运行状态,同时根据情况发起Leader选举。

  • 创建内存数据库ZKDatabase。

ZKDatabase是ZooKeeper的内存数据库,负责管理ZooKeeper的所有会话记录以及DataTree和事务日志的存储。

  • 初始化QuorumPeer。

在步骤5中我们已经提到,QuorumPeer是ZooKeeperServer的托管者,因此需要将一些核心组件注册到QuorumPeer中,包括FileTxnSnapLog、ServerCnxnFactory和ZKDatabase。同时ZooKeeper还是对QuorumPeer配置一些参数,包括服务器地址列表、Leader选举算法和会话超时时间限制等。

  • 恢复本地数据。
  • 启动ServerCnxnFactory主线程。

Leader选举

        Leader选举的步骤如下。

  • 初始化Leader选举。

Leader选举可以说是集群和单机模式启动ZooKeeper最大的不同点。ZooKeeper首先会根据自身的SID(服务器ID)、lastLoggedZxid(最新的ZXID)和当前的服务器epoch(currentEpoch)来生成一个初始化的投票——简单的讲,在初始化过程中,每个服务器都会给自己投票。

然后,ZooKeeper会根据zoo.cfg中的配置,创建相应的Leader选举算法实现。在ZooKeeper中,默认提供了三种Leader选举算法的实现,分别是LeaderElection、AuthFastLeaderElection和FastLeaderElection,可以通过在配置文件(zoo.cfg)中使用electionAlg属性来指定,分别使用数字0~3来表示。从3.4.0版本开始,ZooKeeper废弃了前两种Leader选举算法,只支持FastLeaderElection选举算法了。

在初始化阶段,ZooKeeper会首先创建Leader选举所需的网络I/O层QuorumCnxManager,同时启动对Leader选举端口的监听,等待集群中其他服务器创建连接。

  • 注册JMX服务。
  • 检测当前服务器状态。

在上文中,我们已经提到QuorumPeer是ZooKeeper服务器实例的托管者,在运行期间,QuorumPeer的核心工作,就是不断的检测当前服务器的状态,并作出相应的处理。在正常的情况下,ZooKeeper服务器的状态在LOOKING、LEADING和FOLLOWING/OBSERVING之间进行切换。而在启动阶段,QuorumPeer的初始状态是LOOKING,因此开始进行Leader选举。

  • Leader选举。

ZooKeeper的Leader选举过程,简单的讲,就是一个集群中所有的机器相互之间进行一系列投票,选举产生最适合的机器成为Leader,同时其余机器成为Follower或是Observer的集群机器角色初始化过程。关于Leader选举算法,简而言之,就是集群中哪个机器处理的数据越新(通常我们根据每个服务器处理过的最大ZXID来比较确定其数据是否更新),其越有可能成为Leader。当然,如果集群中的所有机器处理的ZXID一致的话,那么SID最大的服务器成为Leader。

Leader和Follower启动器交互过程

         到这里为止,ZooKeeper已经完成了Leader选举,并且集群中每个服务器都已经确定了自己的角色——通常情况下就分为Leader和Follower两种角色。下面我们来对Leader和Follower在启动期间的工作原理进行讲解,其大致交互流程如下图所示。

        Leader和Follower服务器启动器交互过程包括如下步骤。

  • 创建Leader服务器和Follower服务器。

完成Leader选举之后,每个服务器都会根据自己的服务器角色创建相应的服务器实例,并开始进入各角色的主流程。

  • Leader服务器启动Follower接收器LearnerCnxAcceptor。

在ZooKeeper集群运行期间,Leader服务器需要和所有其余的服务器(“Learner”来指代这类机器)保持连接以确定集群的机器存活情况。LearnerCnxAcceptor接收器用于负责接收所有非Leader服务器的连接请求。

  • Learner服务器开始和Leader建立连接。

所有的Learner服务器在启动完毕后,会从Leader选举的投票结果中找到当前集群的Leader服务器,然后与其建立连接。

  • Leader服务器创建LearnerHandler。

Leader接收到来自其他机器的连接创建请求后,会创建一个LearnerHandler实例。每个LearnerHandler实例都对应了一个Leader与Learner服务器之间的连接。其负责Leader和Learner服务器之间几乎所有的消息通信和数据同步。

  • 向Leader注册。

当和Leader建立起连接后,Leader就会开始向Leader进行注册——所谓的注册,其实就是将Learner服务器自己的基本信息发送给Leader服务器,我们称之为LearnerInfo,包括当前服务器的SID和服务器处理的最新的ZXID。

  • Leader解析Learner信息,计算新的epoch。

Leader服务器在接收到Learner的基本信息后,会解析出该Learner的SID和ZXID,然后根据该Learner的ZXID解析出其对应的epoch_of_learner,和当前Leader服务器的epoch_of_leader进行比较,如果该learner的epoch_of_learner更大的话,那么就更新Leader的epoch:

epoch_of_leader = epoch_of_learner + 1

然后,LearnerHandler会进行等待,直到过半的Learner已经向Leader进行了注册,同时更新了epoch_of_leader之后,Leader就可以确定当前集群的epoch了。

  • 发送Leader状态。

计算出新的epoch之后,Leader会将该信息以一个LEADERINFO消息的形式发送给Learner,同时等待Learner的响应。

  • Leader发送ACK消息。

Follower在收到来自Leader的LEADERINFO消息后,会解析出epoch和ZXID,然后向Leader反馈一个ACKEPOCH响应。

  • 数据同步。

Leader服务器接收到Learner的这个ACK消息后,就可以开始与其进行数据同步了。

  • 启动Leader和Learner服务器。

当有过半的Learner已经完成了数据同步,那么Leader和Learner服务器实例就可以开始启动了。

Leader和Follower启动

        Leader和Follower启动的步骤如下。

  • 创建并启动会话管理器。
  • 初始化ZooKeeper的请求处理链。

和单机版服务器一样,集群模式下,每个服务器都会在启动阶段串联请求处理链,只是根据服务器角色不同,会有不同的请求处理链路。

  • 注册JMX服务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值