zookeeper 原理篇 -Zookeeper 启动流程分析,2021 大厂 Android 面试最火问题
5.通过解析 Zoo.cfg 中的配置信息相关的参数,开始创建 ZookeeperServer 类实例,完成了这一步后,预处理阶段完成
初始化
初始化阶段,则是开始将 Zookeeper 中的相关服务管理类进行创建,大体流程如下:
![](https://static001.geekbang.org/infoq/6b/6b8b92661b13f0593a7865b9bb559963.png)
1.创建了 ZookeeperServer 实例后,Zookeeper 会创建一个 ServerStats 实例,此类用来收集 Zookeeper 运行过程中的统计信息,例如发送客户端的响应包次数,收到的请求包次数,最近启动后最大的延迟和最小延迟等
2.紧接着会创建 Zookeeper 中的数据存储管理器--FileTxnSnaplog 类,此类作为最上层的,提供了一系列了操作数据文件的接口,其中包括操作事务日志和操作快照的接口,而创建当前类实例会根据 zoo.cfg 中的 dataDir 以及 dataLogDir 参数进行构建
3.同样根据解析出来的 zoo.cfg 配置文件中的 tickTime 以及 session 的会话时间来设置对应参数,并且会根据 zookeeper.serverCnxnFactory 参数来确定启动 Zookeeper 的网络连接工厂是基于 Netty 的还是基于 jdk 自身的 Nio 工厂
4.确定工厂类型后,
Zookeeper 会开始初始化一个 Thread,作为整个 Zookeeper 运行过程中的主线程,并且开始初始化 ServerCnxnFactory 实例
5.当 ServerCnxnFactory 实例构建完毕后,开始运行对应的 run 方法中的业务逻辑,此时由于连接工厂已经创建,端口其实已经对外开放了,但是 Zookeeper 此时还未完成启动过程,还无法对外处理请求
6.开始恢复 Zookeeper 的数据,将从事务日志以及之前保存的快照进行数据恢复
7.数据恢复完成后,Zookeeper 开始构建会话管理器--SessionTracker,此类主要负责管理 Session,在创建的时候,将 e xpirationlnterval, nextExpirationTime 和 sessionsWithTimeout 进行计算以及配置,并且会计算出每一个 Session 对应的 SessionID,并且在运行过程中会负责 Session 的会话超时检测等
8.创建完毕后,Zookeeper 会初始化对应的请求过滤链,而在 Zookeeper 中请求的过滤链使用了责任链模式,其中处理的顺序流程主要是 PrepRequestProessor->SyncRequestProessor->FinalRequestProessor 三个请求处理器,至此 Zookeeper 的初始化流程已经做完
注册提供服务
当 Zookeeper 的初始化流程完成后,服务器已经开始到就绪状态了,只需要将对应的信息注册以后即可对外提供服务了,此阶段的流程大概如下:
![](https://static001.geekbang.org/infoq/6b/6b8b92661b13f0593a7865b9bb559963.png)
可以看到此阶段中,Zookeeper 只需要将 JMX 服务注册,以及当前相关实例注册完毕,即可完成单机启动流程,此时的 Zookeeper 已经正常提供服务了
集群模式启动流程
集群模式的启动过程很多和单机模式是一样的,但是由于集群模式下,会有 Leader 机器选举以及数据同步的过程,因此 Zookeeper 的集群模式启动过程要复杂的多,而整个集群的启动过程,大体可以分为五个部分,分别是预处理、初始化、Leader 选举、Leader 与 Follower 交互以及 Leader 与 Follower 启动,其中预处理过程几乎与单机模式一样,唯一的区别在于解析 zoo.cfg 中的连接配置,判断启动模式为集群模式,开始进入集群模式的初始化操作流程而已,因此,我们从集群模式的初始化开始
初始化
初始化过程大体和单机模式差不多,如下:
![](https://static001.geekbang.org/infoq/6b/6b8b92661b13f0593a7865b9bb559963.png)
1.创建并初始化 ServerCnxnFactory
2.创建 Zookeeper 中的数据文件管理器 FileTxnSnaplog
3.在集群模式下,会去创建 QuorumPeer 实例,Quorum 是集群模式下特有的对象,属于 Zookeeper 的托管者,此类的作用是在运行期间,会不停的检测当前服务器实例的状态,并且在需要选举的时候发起选举
4.创建 Zookeeper 中的内存数据库 ZKDatabase 实例,用来记录会话记录以及 DataTree 和事物日志
5.QuorumPeer 实例作为托管者,会在启动过程中,将核心组件信息注册上去,包括之前创建的 ZKDatabase、FileTxnSnaplog 以及服务器列表信息,选举算法等
6.开始恢复数据
7.数据恢复完成后,开始启动 ServerCnxnFactory 中的主线程,运行 run 方法,开始执行服务器选举相关的操作
Leader 选举
选举阶段的流程大概如下:
![](https://static001.geekbang.org/infoq/6b/6b8b92661b13f0593a7865b9bb559963.png)
1.Zookeeper 解析 zoo.cfg 配置文件中的 electionAlg 属性,来确定进行选举的算法是哪一种,在 Zk 中有三种选举算法,分别是 LeaderElection 、 AuthFastLeaderElection 和 FastLeaderElection,分别对应数值 0-3,不过从 3.4 的版本开始,zk 仅支持 FastLeaderElection 选举算法,其他两种被废弃了。同样的,在选举的初始化阶段,zk 会根据自身服务器 ID、lastLoggedZxid 和当前服务器的 epoch 初始化一个选举的票据
2.选举初始化准备好以后,开始注册 JMX 服务
3.前面创建好的 QuorumPeer 实例会不断检测当前的服务器状态,在正常情况下,QuorumPeer 的状态应该是 LOOKING,才会开始进行选举操作
4.开始进行选举操作,简单来说,zk 中一般是 ZXID 最大的机器成为 Leader,如果 ZXID 一样,SID 越大的则成为 Leader。(zk 的详细选举流程,则在后续的文章中分析)
Leader 与 Follower 交互
当选举出 Leader 机器以后,其他的机器则会开始与 Leader 进行交互,进行数据同步等操作,此阶段的流程大致如下:
![](https://static001.geekbang.org/infoq/6b/6b8b92661b13f0593a7865b9bb559963.png)
1.不同角色(Leader 和 Follower)的 zookeeper 服务器在选举完毕后,会开始进入各自角色的主流程
评论