作者:leesf    掌控之中,才会成功;掌控之外,注定失败。出处:http://www.cnblogs.com/leesf456/p/6105276.html尊重原创,大家功能学习进步; 

一、前言

  前面已经了解了Zookeeper会话相关知识点,接着来学习Zookeeper服务端相关细节。

二、服务端

  服务端整体架构如下

  Zookeeper服务器的启动,大致可以分为以下五个步骤

  1. 配置文件解析。

  2. 初始化数据管理器。

  3. 初始化网络I/O管理器。

  4. 数据恢复。

  5. 对外服务。

  2.1 单机版服务器启动

  单机版服务器的启动其流程图如下

  上图的过程可以分为预启动初始化过程。

  1. 预启动

    1. 统一由QuorumPeerMain作为启动类。无论单机或集群,在zkServer.cmd和zkServer.sh中都配置了QuorumPeerMain作为启动入口类。

    2. 解析配置文件zoo.cfg。zoo.cfg配置运行时的基本参数,如tickTime、dataDir、clientPort等参数。

    3. 创建并启动历史文件清理器DatadirCleanupManager。对事务日志和快照数据文件进行定时清理。

    4. 判断当前是集群模式还是单机模式启动。若是单机模式,则委托给ZooKeeperServerMain进行启动。

    5. 再次进行配置文件zoo.cfg的解析。

    6. 创建服务器实例ZooKeeperServer。Zookeeper服务器首先会进行服务器实例的创建,然后对该服务器实例进行初始化,包括连接器、内存数据库、请求处理器等组件的初始化。

  2. 初始化

    1. 创建服务器统计器ServerStats。ServerStats是Zookeeper服务器运行时的统计器。

    2. 创建Zookeeper数据管理器FileTxnSnapLog。FileTxnSnapLog是Zookeeper上层服务器和底层数据存储之间的对接层,提供了一系列操作数据文件的接口,如事务日志文件和快照数据文件。Zookeeper根据zoo.cfg文件中解析出的快照数据目录dataDir和事务日志目录dataLogDir来创建FileTxnSnapLog。

    3. 设置服务器tickTime和会话超时时间限制。

    4. 创建ServerCnxnFactory。通过配置系统属性zookeper.serverCnxnFactory来指定使用Zookeeper自己实现的NIO还是使用Netty框架作为Zookeeper服务端网络连接工厂。

    5. 初始化ServerCnxnFactory。Zookeeper会初始化Thread作为ServerCnxnFactory的主线程,然后再初始化NIO服务器。

    6. 启动ServerCnxnFactory主线程。进入Thread的run方法,此时服务端还不能处理客户端请求。

    7. 恢复本地数据。启动时,需要从本地快照数据文件和事务日志文件进行数据恢复。

    8. 创建并启动会话管理器。Zookeeper会创建会话管理器SessionTracker进行会话管理。

    9. 初始化Zookeeper的请求处理链。Zookeeper请求处理方式为责任链模式的实现。会有多个请求处理器依次处理一个客户端请求,在服务器启动时,会将这些请求处理器串联成一个请求处理链。

    10. 注册JMX服务。Zookeeper会将服务器运行时的一些信息以JMX的方式暴露给外部。

    11. 注册Zookeeper服务器实例。将Zookeeper服务器实例注册给ServerCnxnFactory,之后Zookeeper就可以对外提供服务。

  至此,单机版的Zookeeper服务器启动完毕。

  2.2 集群服务器启动

  单机和集群服务器的启动在很多地方是一致的,其流程图如下

  上图的过程可以分为预启动、初始化、Leader选举、Leader与Follower启动期交互过程、Leader与Follower启动等过程。

  1. 预启动

    1. 统一由QuorumPeerMain作为启动类。

    2. 解析配置文件zoo.cfg。

    3. 创建并启动历史文件清理器DatadirCleanupFactory。

    4. 判断当前是集群模式还是单机模式的启动。在集群模式中,在zoo.cfg文件中配置了多个服务器地址,可以选择集群启动。

  2. 初始化

    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主线程。

  3. 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选举端口的监听,等待集群中其他服务器创建连接。

    2. 注册JMX服务。

    3. 检测当前服务器状态。运行期间,QuorumPeer会不断检测当前服务器状态。在正常情况下,Zookeeper服务器的状态在LOOKING、LEADING、FOLLOWING/OBSERVING之间进行切换。在启动阶段,QuorumPeer的初始状态是LOOKING,因此开始进行Leader选举。

    4. Leader选举。通过投票确定Leader,其余机器称为Follower和Observer。具体算法在后面会给出。

  4. Leader和Follower启动期交互过程

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

    2. Leader服务器启动Follower接收器LearnerCnxAcceptor。运行期间,Leader服务器需要和所有其余的服务器(统称为Learner)保持连接以确集群的机器存活情况,LearnerCnxAcceptor负责接收所有非Leader服务器的连接请求。

    3. Leader服务器开始和Leader建立连接。所有Learner会找到Leader服务器,并与其建立连接。

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

    5. 向Leader注册。Learner完成和Leader的连接后,会向Leader进行注册,即将Learner服务器的基本信息(LearnerInfo),包括SID和ZXID,发送给Leader服务器。

    6. Leader解析Learner信息,计算新的epoch。Leader接收到Learner服务器基本信息后,会解析出该Learner的SID和ZXID,然后根据ZXID解析出对应的epoch_of_learner,并和当前Leader服务器的epoch_of_leader进行比较,如果该Learner的epoch_of_learner更大,则更新Leader的epoch_of_leader = epoch_of_learner + 1。然后LearnHandler进行等待,直到过半Learner已经向Leader进行了注册,同时更新了epoch_of_leader后,Leader就可以确定当前集群的epoch了。

    7. 发送Leader状态。计算出新的epoch后,Leader会将该信息以一个LEADERINFO消息的形式发送给Learner,并等待Learner的响应。

    8. Learner发送ACK消息。Learner接收到LEADERINFO后,会解析出epoch和ZXID,然后向Leader反馈一个ACKEPOCH响应。

    9. 数据同步。Leader收到Learner的ACKEPOCH后,即可进行数据同步。

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

  5. Leader和Follower启动

    1. 创建启动会话管理器。

    2. 初始化Zookeeper请求处理链,集群模式的每个处理器也会在启动阶段串联请求处理链。

    3. 注册JMX服务。

  至此,集群版的Zookeeper服务器启动完毕。

三、总结

这篇博文个人感觉了解大致流程就可以,只是辅助理解zookeeper服务端的内部原理,当然能透彻理解更好,毕竟内容比较深入;

Zookeeper系列(十)zookeeper的服务端启动详述的更多相关文章

  1. zookeeper源码分析之一服务端启动过程

    zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...

  2. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  3. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  4. (二)Netty源码学习笔记之服务端启动

    尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6129971.html  本文将不会对netty中每个点分类讲解,而是一个服务端启 ...

  5. Netty 源码(一)服务端启动

    Netty 源码(一)服务端启动 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) ServerBootstap 创建时序图如 ...

  6. Netty之旅三:Netty服务端启动源码分析,一梭子带走!

    Netty服务端启动流程源码分析 前记 哈喽,自从上篇<Netty之旅二:口口相传的高性能Netty到底是什么?>后,迟迟两周才开启今天的Netty源码系列.源码分析的第一篇文章,下一篇我 ...

  7. Netty源码解析 -- 服务端启动过程

    本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列 ...

  8. Netty源码分析之服务端启动过程

    一.首先来看一段服务端的示例代码: public class NettyTestServer { public void bind(int port) throws Exception{ EventL ...

  9. Netty 4源码解析:服务端启动

    Netty 4源码解析:服务端启动 1.基础知识 1.1 Netty 4示例 因为Netty 5还处于测试版,所以选择了目前比较稳定的Netty 4作为学习对象.而且5.0的变化也不像4.0这么大,好 ...

随机推荐

  1. ASP.NET Core中间件实现分布式 Session(转载)

    ASP.NET Core中间件实现分布式 Session 1. ASP.NET Core中间件详解 1.1. 中间件原理 1.1.1. 什么是中间件 1.1.2. 中间件执行过程 1.1.3. 中间件 ...

  2. 使用.Net Core 2.2创建windows服务

    使用.Net Core 2.2创建windows服务 我的环境 win 10 home Visual Studio 2019 v16.1.3 安装有.net core 2.2 创建项目 编辑项目文件 ...

  3. 一个SDL2.0程序的分析

    //把图片加载到SDL_Texture SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){       ...

  4. 微信小程序上传图片更新图像

    解决思路: 1. 调用wx.chooseImage 选择图片 2.wx.uploadFile 上传图片 3.调用后台接口进行修改操作 修改原来的头像 wx.chooseImage({ success: ...

  5. 用Leangoo看板进行可视化的缺陷跟踪管理

    转自:https://www.leangoo.com/10464.html 缺陷管理通常关注如下几个方面: 1. 缺陷的处理速度 2. 缺陷处理的状态 3. 缺陷的分布 4. 缺陷产生的原因 使用Le ...

  6. 第一章、前端之html

    目录 第一章.前端之html 一. html介绍 第一章.前端之html 一. html介绍 web服务本质 import socket sk = socket.socket() sk.bind((& ...

  7. Windows下同时安装两个版本Jdk

    在项目开发中遇到了jdk版本切换的问题,于是尝试在电脑中安装jdk1.6和jdk1.7,话不多说马上开始 1 准备好两个版本的jdk路径 2 设置两个JAVA_HOME 3 设置总的动态切换的JAVA ...

  8. MyBatis 插入失败后爆出 500 ,如何捕获异常?

    我们在使用 Mybatis 的时候,会出现以下场景 数据表里有一些字段被设置为了 不可为 null 但是我们的用户在提交表单的时候没有提交所需的 字段数据 然后 Mybatis 在数据库做操作的时候就 ...

  9. 一图一知-TS的基本数据类型

  10. PAT乙级1039

    题目链接 https://pintia.cn/problem-sets/994805260223102976/problems/994805283241443328 题解 用两个字符串表示两个箱子,一 ...