在26节对集群版服务端启动进行了一个概述,这一部分对集群版server启动,到选举出leader的小结,也是对前面27-35的一个小结
前情提要
这里把26节server启动的预启动,初始化以及leader选举部分提出来
预启动
1. 统一由QuorumPeerMain作为启动类。
2. 解析配置文件zoo.cfg。
3. 创建并启动历史文件清理器DatadirCleanupFactory。
4. 判断当前是集群模式还是单机模式的启动。
在集群模式中,在zoo.cfg文件中配置了多个服务器地址,可以选择集群启动。
上述代码都在org.apache.zookeeper.server.quorum.QuorumPeerMain#initializeAndRun中,截图如下
![](https://img.haomeiwen.com/i4871751/73ef4da26adaa575.png)
初始化
1. 创建ServerCnxnFactory。
2. 初始化ServerCnxnFactory。
3. 创建Zookeeper数据管理器FileTxnSnapLog。
4. 创建QuorumPeer实例。
Quorum是集群模式下特有的对象,是Zookeeper服务器实例(ZooKeeperServer)的托管者,QuorumPeer代表了集群中的一台机器
在运行期间,QuorumPeer会不断检测当前服务器实例的运行状态,同时根据情况发起Leader选举。
5. 创建内存数据库ZKDatabase。
ZKDatabase负责管理ZooKeeper的所有会话记录以及DataTree和事务日志的存储。
6. 初始化QuorumPeer。
将核心组件如FileTxnSnapLog、ServerCnxnFactory、ZKDatabase注册到QuorumPeer中,同时配置QuorumPeer的参数,如服务器列表地址、Leader选举算法和会话超时时间限制等。
7. 恢复本地数据。
8. 启动ServerCnxnFactory主线程。
其中1-6步在org.apache.zookeeper.server.quorum.QuorumPeerMain#runFromConfig中,顺序不完全一样
![](https://img.haomeiwen.com/i4871751/9ab8227bee99b57e.png)
7-8步在org.apache.zookeeper.server.quorum.QuorumPeer#start中
@Override
public synchronized void start() {
loadDataBase();//从事务日志目录dataLogDir和数据快照目录dataDir中恢复出DataTree数据
cnxnFactory.start();//开启对客户端的连接端口,启动ServerCnxnFactory主线程
startLeaderElection();//创建出选举算法
super.start();//启动QuorumPeer线程,在该线程中进行服务器状态的检查
}
leader选举
1. 初始化Leader选举算法
集群模式特有,Zookeeper首先会根据自身的服务器ID(SID)、最新的ZXID(lastLoggedZxid)和当前的服务器epoch(currentEpoch)来生成一个初始化投票
在初始化过程中,每个服务器都会给自己投票。然后,根据zoo.cfg的配置,创建相应Leader选举算法实现
Zookeeper提供了三种默认算法(LeaderElection、AuthFastLeaderElection、FastLeaderElection),可通过zoo.cfg中的electionAlg属性来指定,但现只支持FastLeaderElection选举算法。
在初始化阶段,Zookeeper会创建Leader选举所需的网络I/O层QuorumCnxManager,同时启动对Leader选举端口的监听,等待集群中其他服务器创建连接。
源码在QuorumPeer#startLeaderElection中
完成自己的投票以及投票算法的获取
2.注册JMX服务。
代码在org.apache.zookeeper.server.quorum.QuorumPeer#run中
3.检测当前服务器状态
运行期间,QuorumPeer会不断检测当前服务器状态。在正常情况下,Zookeeper服务器的状态在LOOKING、LEADING、FOLLOWING/OBSERVING之间进行切换。在启动阶段,QuorumPeer的初始状态是LOOKING,因此开始进行Leader选举。
4. Leader选举。
通过投票确定Leader,其余机器称为Follower和Observer。具体算法在后面会给出。
源码体现在org.apache.zookeeper.server.quorum.Election#lookForLeader
默认实现org.apache.zookeeper.server.quorum.FastLeaderElection#lookForLeader
上述步骤在
![](https://img.haomeiwen.com/i4871751/47ef996ac769d4d0.png)
2-4的源码步骤太长了,这里不贴出来了,就在QuorumPeer#run中
27-35小结代码总结
之前讲到集群版启动流程如下图
![](https://img.haomeiwen.com/i4871751/c59cee8f9ee4931f.png)
前面讲的内容分别对应哪几个步骤
32 - 35节讲解SeverCnxn(factory)以及对应nio实现
对应
![](https://img.haomeiwen.com/i4871751/b90c9cd855386175.png)
27节QuorumPeerConfig,31节QuorumPeer对应
![](https://img.haomeiwen.com/i4871751/de2ddb72248af527.png)
调用方是QuorumPeerMain#runFromConfig
对应主要逻辑在QuorumPeer#start
public synchronized void start() {
loadDataBase();//从事务日志目录dataLogDir和数据快照目录dataDir中恢复出DataTree数据
cnxnFactory.start();//开启对客户端的连接端口,启动ServerCnxnFactory主线程
startLeaderElection();//创建出选举算法
super.start();//启动QuorumPeer线程,在该线程中进行服务器状态的检查
}
28节集群验证器,29节选举时的IO管理QuorumCnxManager,30节leader的选举算法FastLeaderElection完成了下述部分
![](https://img.haomeiwen.com/i4871751/390a6cb3d3768191.png)
网友评论