服务器架构
单机版服务器启动
ZooKeeper服务器的启动,大体可以分为以下五个主要步骤:配置文件解析、初始化数据管理器、初始化网络I/O管理器、数据恢复和对外服务
。
预启动:
-
统一由QuorumPeerMain作为启动类
无论是单机版还是集群模式启动ZooKeeper服务器,在zkServer.cmd和zkServer.sh两个脚本中,都配置了使用org.apache.zookeeper.server.quorum.QuorumPeerMain作为启动入口类
。 -
解析配置文件zoo.cfg
ZooKeeper首先会进行配置文件的解析,配置文件的解析其实就是对zoo.cfg文件的解析。在5.1.2节中,我们曾经提到在部署ZooKeeer服务器时,需要使用到zoo.cfg这个文件。该文件配置了ZooKeeper 运行时的基本参数,包括tickTime 、dataDir和clientPort等参数。 -
创建并启动历史文件清理器DatadirCleanupmanager
从3.4.0版本开始,ZooKeeper 增加了自动清理历史数据文件的机制,包括对事务日志和快照数据文件进行定时清理。 -
判断当前是集群还是单机模式的启动
ZooKeeper根据步骤2中解析出的集群服务器地址列表来判断当前是集群模式还是单机模式,如果是单机模式,那么就委托给ZooKeeperServerMain 进行启动处理。 -
再次进行配置文件zoo.cfg的解析
-
创建服务器实例ZookeeperServer
org.apache.zookeeper.server.ZooKeeperServer是单机版ZooKeeper服务端最为核心的实体类。ZooKeeper服务器首先会进行服务器实例的创建,接下去的步骤则都是对该服务器实例的初始化工作,包括连接器、内存数据库和请求处理器等组件的初始化。
初始化:
-
创建服务器统计器ServerStats
ServerStats是ZooKeeper服务器运行时的统计器,包含了最基本的运行时信息:
-
创建Zookeeper数据管理器FileTxnSnapLog
FileTxnSnapLog是ZooKeeper.上层服务器和底层数据存储之间的对接层,提供了一系列操作数据文件的接口,包括事务日志文件和快照数据文件。ZooKeeper根据: zoo.cfg文件中解析出的快照数据目录dataDir和事务日志目录datal ogDir来创建FileTxnSnapLog。 -
设置服务器tickTime和会话超时时间限制
-
创建ServerCnxnFactory
在早期版本中,ZooKeeper都是自己实现NIO框架,从3.4.0版本开始,引入了Netty。开发者可以通过配置系统属性zookeeper . serverCnxnFactory来指定使用ZooKeeper自己实现的NIO还是使用Netty框架来作为ZooKeeper服务端网络连接工厂。 -
初始化ServerCnxnFactory
ZooKeeper首先会初始化一个Thread,作为整个ServerCnxnFactory的主线程,然后再初始化NIO服务器。 -
启动ServerCnxnFactory主线程
启动步骤5中已经初始化的主线程ServerCnxnFactory的主逻辑(run方法)。需要注意的一点是,虽然这里ZooKeeper的NIO服务器已经对外开放端口,客户端能够访问到ZooKeeper的客户端服务端口2181,但是此时ZooKeeper服务器是无法正常处理客户端请求的。 -
恢复本地数据
每次在ZooKeeper启动的时候,都需要从本地快照数据文件和事务日志文件中进行数据恢复。 -
创建并启动会话管理器
在ZooKeeper启动阶段,会创建一个会话管理器SessionTracker。它主要负责ZooKeeper 服务端的会话管理。创建SessionTracker的时候,会初始化expirationInterval、nextExpirationTime和sessionsWi thTimeout (用于保存每个会话的超时时间),同时还会计算出一一个初始化的sessionID。
SessionTracker初始化完毕之后,Zookeeper就会立即开始会话管理器的超时检查。 -
初始化Zookeeper的请求处理链
ZooKeeper的请求处理方式是典型的责任链模式的实现,在ZooKeeper服务器上,会有多个请求处理器依次来处理一个客户端请求。在服务器启动的时候,会将这些请求处理器串联起来形成一个请求处理链。单机版服务器的请求处理链主要包括PrepRequestProcessor. SyncRequestProcessor和FinalRequestProcessor三个请求处理器
。
-
注册JMX服务
ZooKeeper会将服务器运行时的一些信息以JMX的方式暴露给外部。 -
注册Zookeeper服务器实例
在步骤6中,ZooKeeper 已经将ServerCnxnFactory主线程启动,但是同时我们提到此时ZooKeeper依旧无法处理客户端请求,原因就是此时网络层尚不能够访问ZooKeeper服务器实例。在经过后续步骤的初始化后,ZooKeeper服务器实例已经初始化完毕,只需要注册给ServerCnxnFactory 即可,之后,ZooKeeper就可以对外提供正常的服务了。
至此,单机版的Zookeeper服务器启动完毕。