Zookeeper数据同步流程

2023-05-16

在服务器启动阶段,会进行磁盘数据的恢复,完成数据恢复后就会进行Leader选举。一旦选举产生Leader服务器后,就立即开始进行集群间的数据同步,在整个过程中,Zookeeper都处于不可用状态,直到数据同步完毕,Zookeeper才可以对外提供正常服务。

一、数据初始化

在Zookeeper服务器启动期间,首先会进行数据初始化工作,用于将存储在磁盘上的数据文件加载到Zookeeper服务器内存中。完整的数据初始化流程如下:

图片

数据的初始化从磁盘中加载数据的过程,主要包括了从快照文件中加载快照数据和根据事务日志进行数据订正两个过程。

1. 初始化FileTxnSnapLog

FileTxnSnapLog是Zookeeper事务日志和快照数据访问层,用于衔接上层业务与底层数据存储,底层数据包含了事务日志和快照数据两部分,因此FileTxnSnapLog内部又分为FileTxnLog和FileSnap的初始化,分别代表事务日志管理器和快照数据管理器的初始化。

2. 初始化ZKDatabase

完成FileTxnSnapLog的初始化后,就要开始构建内存数据库ZKDatabase了,在初始化过程中,首先会构建一个初始化DataTree,同时会将步骤1中初始化的FileTxnSnapLog交给ZKDatabase,以便内存数据库能够对事务日志和快照数据进行访问。

3. 创建PlayBackListener监听器

PlayBackListener监听器主要用来接收事务应用过程中的回调,在Zookeeper数据恢复后期,会有一个事务订正的过程,在这个过程中,会回调PlayBackListener监听器来进行对应的数据订正。PlayBackListener会将这些刚刚应用到内存数据库中的事务转存到ZKDatabase.committedLog中,以便集群中服务器间进行快速的数据同步。

4. 处理快照文件

完成内存数据库的初始化后,java培训Zookeeper就可以开始从磁盘中恢复数据了,每一个快照数据文件中都保存了Zookeeper服务器几乎全量的数据,因此首先会从这些快照文件开始加载。

5. 获取最新的100个快照文件

Zookeeper会加载最新的至多100个快照文件。

6. 解析快照文件

如果正确性校验通过的话,那么通常只会解析最新的那个快照文件。只有当最新的快照文件不可用时,才会逐个解析,直到将这100个文件全部解析完。

7. 获取最新的ZXID

完成步骤6后,就已经基于快照文件构建了一个完整的DataTree实例和sessionsWithTimeouts集合汇总,此时根据这个快照文件的文件名就可以解析出一个最新的ZXID:zxid_for_snap,代表了Zookeeper开始进行数据快照的时刻。

8. 处理事务日志

经过前面7步流程的处理,此时Zookeeper服务器内存中已经有了一份近似全量的数据了,现在开始就要通过事务日志来更新增量数据了。

9. 获取所有zxid_for_snap之后提交的事务

Zookeeper中数据的快照机制决定了快照文件中并非包含了所有的事务操作,但是未被包含在快照文件中的那部分事务操作可以通过数据订正来实现,因此,我们这里只需要从事务日志中获取所有ZXID比步骤7得到的zxid_for_snap大的事务操作即可。

10. 事务应用

获取到所有ZXID大于zxid_for_snap的事务后,将其逐个应用到之前基于快照文件恢复出来的

DataTree和sessionsWithTimeouts中。

每当有一个事务被应用到内存数据库汇总,Zookeeper同时会回调PlayBackListener监听器,将这一事务操作记录转换成Proposal,并保存到ZKDatabase.committedLog中,以便Follower进行快速同步。

11. 获取最新ZXID

待所有的事务都被完整地应用到内存数据库中之后,基本上也就完成了数据的初始化过程,此时再获取一个ZXID,用来表示上次服务器正常运行时提交的最大事务ID。

12. 校验epoch

每次选举产生一个新的Leader服务器之后,就会生成一个新的epoch,在完成数据加载后,Zookeeper从步骤11中确定的ZXID中解析出事务处理的Leader周期,同时也会从磁盘文件中读取出上次记录的最新epoch值,进行校验。

接下来,我们就来看看数据同步的流程是怎样的。

二、数据同步

在介绍数据同步流程中,我们使用Learner代表所有非Leader服务器。

在集群服务器启动过程中,当整个集群完成Leader选举之后,Learner服务器会向Leader服务器进行注册,当所有服务器都注册完之后,就进入到了数据同步环节。数据同步过程就是Leader服务器将那些没有在Learner服务器上提交过的事务请求同步给Learner服务器。

大体过程如下:

图片

获取Learner状态

在注册Learner的最后阶段,Learner服务器会发送给Leader服务器一个ACKEPOCH数据包,Leader会从这个数据包中解析出该LearnerDE currentEpoch和lastZxid。

数据同步初始化

在开始数据同步之前,Leader服务器会进行数据同步初始化,首先会从Zookeeper的内存数据库中提取出事务请求对应的提议缓存队列proposals,同时完成以下三个ZXID值的初始化:

  • peerLastZxid:该Learner服务器最后处理的ZXID

  • minCommittedLog:Leader服务器提议缓存队列committedLog中的最小ZXID

  • maxCommittedLog:Leader服务器提议缓存队列committedLog中的最大ZXID

Zookeeper集群数据同步分四类:直接差异化同步(DIFF同步)、先回滚再差异化同步(TRUNC+DIFF同步)、仅回滚同步(TRUNC同步)和全量同步(SNAP同步)。java培训在初始化节点,Leader服务器会优先初始化以全量同步方式来同步数据,但不是最终的同步方式,最终的同步方式会根据Leader和Learner服务器之间的数据差异情况来决定。

直接差异化同步(DIFF同步)

场景:peerLastZxid介于minCommittedLog和maxCommittedLog之间。

对于这种场景,直接使用直接差异化同步方式即可。Leader服务器会首先向这个Learner发送一个DIFF指令,用于通知Learner进入差异化数据同步阶段。在实际Proposal同步过程中,针对每个Proposal,Leader服务器都会通过发送两个数据包来完成,分别是PROPOSAL内容数据包和COMMIT指令数据包。

举例说明:假如某个时刻Leader服务器的提议缓存队列对应的ZXID依次是:

0x500000001、0x500000002、0x500000003、0x500000004、0x500000005

而Learner服务器最后处理的ZXID为0x500000003,于是Leader服务器就会依次将0x500000004和0x500000005两个提议同步给Learner服务器,同步过程中的数据包发送顺序如下:

发送顺序数据包类型对应的ZXID
1PROPOSAL0x500000004
2COMMIT0x500000004
3PROPOSAL0x500000005
4COMMIT0x500000005

通过以上四个数据包的发送,Learner服务器就可以接收到自己和Leader服务器的所有差异数据,Leader服务器在发送完差异数据之后,就会将该Learner加入到forwardingFollowers或observingLearners队列中。随后Leader还会立即发送一个NEWLEADER指令,用于通知Learner已经将提议缓存队列中的Proposal都同步给你自己了。

接下来,我们看看Learner对Leader发送过来的数据包是如何处理的?

Learner首先会接收到一个DIFF指令,于是便确定了进入DIFF同步阶段。然后依次收到上述四个数据包,Learner会依次将其应用到内存数据库中,然后在接收到Leader的NEWLEADER指令后,Learner会反馈给Leader一个ACK消息,表明自己也完成了对提议缓存队列中Proposal的同步。

Leader在接收到来自Learner的这个ACK消息后,就认为当前Learner已经完成了数据同步,同时进入过半策略等待阶段,直到集群中有过半的Learner机器响应了Leader这个ACK消息。一旦满足过半策略后,Leader服务器就会向所有已经完成数据同步的Learner发送一个UPTODATE指令,用来通知Learner集群中已经有过半的机器完成了数据同步,集群已经具备了对外服务的能力了。

Learner在接收到这个来自Leader的UPTODATE指令后,会终止数据同步流程,然后向Leader再次反馈一个ACK消息。整个直接差异化同步过程中涉及的Leader和Learner之间的数据包通信如下图所示:

图片

先回滚再差异化同步(TRUNC+DIFF同步)

在上述场景中有一个罕见的特殊场景:假如有A、B、C三台机器,B是Leader,此时的Leader_epoch为5,当前已经被集群中大部分机器都提交的ZXID包括:0x500000001和0x500000002。此时,Leader正要处理0x500000003,并且已经将该事务写入到了Leader本地的事务日志中,就在Leader要将该Proposal发送给其他Follower机器进行投票的时候,Leader服务器挂了,开始新一轮选举,同时Leader_epoch变更为6,之后A和C继续对外进行服务,又提交了0x600000001和0x600000002两个事务,此时B再次启动,并开始数据同步。

简单来说,上面这个场景就是Leader服务器已经将事务记录到了本地事务日志中,但是没有成功发起Proposal流程的时候就挂了,在这个特殊场景汇总,我们看到peerLastZxid和minCommittedLog和maxCommittedLog的值分别是0x500000003、0x500000001和0x600000002,显然,peerLastZxid介于minCommittedLog和maxCommittedLog之间。

对于这种特殊场景,就是用先回滚再差异化同步的方式。当Leader服务器发现某个Learner包含了一条自己没有的事务记录,那么就需要让该Learner进行事务回滚,回滚到Leader服务器上存在的,同时也是最接近于peerLastZxid的ZXID。在上述示例中,Leader需要Learner回滚到ZXID为0x500000002的事务记录。

先回滚再差异化同步的数据同步方式在具体实现上和差异化同步是一样的,都会将差异化的Proposal发送给Learner,同步过程中的数据包发送顺序如下:

发送顺序数据包类型对应的ZXID
1TRUNC0x500000002
2PROPOSAL0x600000001
3COMMIT0x600000001
4PROPOSAL0x600000002
5COMMIT0x600000002

仅回滚同步(TRUNC同步)

场景:peerLastZxid大于maxCommittedLog。

这种场景其实就是上述先回滚再差异化同步的简化模式,Leader会要求Learner回滚到ZXID值为maxCommitedLog对应的事务操作。

全量同步(SNAP同步)

场景1:peerLastZxid小于maxCommittedLog。

场景2:Leader上没有提议缓存队列,peerLastZxid不等于maxCommittedLog。

在这两种场景下,Leader服务器都无法直接使用提议缓存队列和Learner进行数据同步,因此只能进行全量同步。

全量同步就是Leader服务器将本机上的全量内存数据都同步给Learner。Leader服务器首先向Learner发送一个SNAP指令,通知Learner即将进行全量数据同步,随后,Leader会从内存数据库中获取到全量的数据节点和会话超时时间记录器,将它们序列化后传输给Learner。Learner服务器接收到该全量数据后,会对器反序列化后载入到内存数据库中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Zookeeper数据同步流程 的相关文章

  • ZooKeeper的学习与应用

    转载 http blog csdn net rengq126 article details 7393227 最近大概学习了一下ZooKeeper 本身并没有深入 LGG尝试着在虚拟机里面搭了平台 看了看一些教材 从网上到处看别人的博文并引
  • zookeeper介绍

    1 简介 Zookeeper 分布式服务框架是Apache Hadoop 的一个子项目 它主要是用来解决分布式应用中经常遇到的一些数据管理问题 如 统一命名服务 状态同步服务 集群管理 分布式应用配置项的管理等 Zookeeper 作为一个
  • Eureka和Zookeeper的区别

    Eureka和Zookeeper的区别 Mysql Oracle SqlServer等关系型数据库遵循的原则是 ACID 原则 即 A 原子性 C 一致性 I 独立性 D 持久性 Redis Mogodb 等非关系型数据库遵循的原则是 CA
  • 启动dubbo项目提示zk连接不上 Will not attempt to authenticate using SASL

    背景 本来自己本地能正常连接zk 启动项目 突然就不行了 这种莫名其妙的错误 令人头大 虽然找到了解决方法 但不知其原因 希望有大佬一起交流下 解决方案 查看zookeeper安装目录下的 conf zoo cfg文件 查看dataDir的
  • 【Dubbo】Dubbo(二)简单实践

    Dubbo 二 实践 安装注册中心 下载zookeeper 在zookeeper路径下新增date文件夹存储数据 conf路径下新增zoo cfg 编辑zoo cfg 修改数据目录dataDir为新增的data文件夹 其他与zoo samp
  • ZooKeeper(八)伸缩性

    一 ZooKeeper中Observer 1 1 ZooKeeper角色 经过前面的介绍 我想大家都已经知道了在ZooKeeper集群当中有两种角色Leader和Follower Leader可以接受client 请求 也接收其他Serve
  • Zookeeper缩容5缩3操作记录(二)

    测试目标 测试5台缩3台zk 先shutdown 一台5 再将1 2 3配置修改为1 2 3 逐一重启 是否会发生脑裂 测试过程 准备1 2 3 4 5 五台 3为leader 将5 shutdown 1 将1配置修改为1 2 3 重启 结
  • Arthas 定位CPU跑满问题,源头竟是Apache Beanutils

    一 背景 大早上 线上k8s 机子 某个机子 cpu 飙高 导致k8s 健康检查失败 线上环境会自动执行jstack 上传到oss 通知到 钉钉告警群 直接分析锁 cpu 高的线程 二 过程分析 2 1 排查cpu 占用最高的线程 使用js
  • Zookeeper的常见面试题

    1 Zookeeper 1 1 Zookeeper基本概念 Zookeeper作为一个优秀高效且可靠的分布式协调框架 ZooKeeper 在解决分布式数据一致性问题时并没有直接使用Paxos算法 而是专门定制了一致性协议叫做 ZAB Zoo
  • 《从Paxos到ZooKeeper》读书笔记之第一章(二)

    从Paxos到ZooKeeper 读书笔记之第一章 二 1 2从ACID到CAP BASE 这一节由三小节 从大家数值的数据库事务的四个特性 引出来分布式事务的概念 通过对ACID模型的讨论 提出如何构建一个兼顾可用性和一致性的分布式系统方
  • kafka详解及集群环境搭建

    一 kafka详解 安装包下载地址 https download csdn net download weixin 45894220 87020758 1 1Kafka是什么 1 Kafka是一个开源消息系统 由Scala写成 是由Apac
  • Zookeeper 基本操作

    Zookeeper 基本操作 文章目录 Zookeeper 基本操作 1 查看zk的运行状态 2 客户端连接zk 3 ls 查看 4 get 获取节点数据和更新信息 5 stat 获得节点的更新信息 6 ls2 ls命令和stat命令的整合
  • Docker搭建zookeeper

    问题背景 前言 本文参考自 docker compose快速搭建Zookeeper集群 熬到凌晨三点多验证部署成功 网上有很多文章已经无法正确部署了 因为有些东西版本升级了 版本跟不上就会报错 还有一种更加详细更加全面的部署方式 Docke
  • zookeeper学习草稿纸

    指令重排序 https baijiahao baidu com s id 1701616903992143186 wfr spider for pc JVM JDK JRE 静态方法为什么不能调用非静态成员 重载和重写的区别 可变参数 基本
  • Spring-boot+Dubbo(直连模式)

    Spring boot Dubbo 直连模式 Demo 这里应该有很多人会问 直连模式 什么鬼啊 一般情况下我们进行微服务开发时 都是通过zookeeper等注册中心来实现服务的提供和引用的 那直连模式没啥用啊 其实不然 直连模式大有用处
  • 如何实现一个分布锁?

    基本概念 为何需要分布式锁 传统环境中的情况 在程序开发过程中不得不考虑的就是并发问题 在java中对于同一个jvm而言 jdk已经提供了lock和同步等 但是在分布式情况下 往往存在多个进程对一些资源产生竞争关系 而这些进程往往在不同的机
  • zookeeper 搭建教程(完整版)

    zookeeper 搭建教程 完整版 1 解压zookeeper文件 root master tar zxvf opt software apache zookeeper 3 5 7 bin tar gz C opt module 修改文件
  • 从zookeeper官方文档系统学习zookeeper

    从zookeeper官方文档系统学习zookeeper 1 zookeeper 2 zookeeper 文档 3 zookeeper 单机版 3 1 配置 3 2 启动 3 3 验证 4 zookeeper 集群版 4 1 配置 4 2 启
  • 大数据技术之Zookeeper

    大数据技术之Zookeeper 一 zookeeper特点 二 zookeeper单机模式 三 zookeeper 常用命令 四 查看zookeeper 状态的几种方式 一 zookeeper特点 Zookeeper 文件系统 通知机制 1
  • 终于找到了最新版的Zookeeper入门级教程,建议收藏!

    小熊学Java https javaxiaobear cn 1 分布式一致性 1 CAP 理论 CAP 理论指出对于一个分布式计算系统来说 不可能同时满足以下三点 一致性 在分布式环境中 一致性是指数据在多个副本之间是否能够保持一致的特性

随机推荐

  • QML 地图可拖拽位置标签组件

    在地图上显示位置信息时 xff0c 有时候需要同时显示该位置的详细信息 该组件可在地图上显示一个连接到地图地理位置的标签框 xff0c 该标签框可点击进行拖拽 在地理位置改变 地图缩放 地图平移时 xff0c 该标签框的相对位置保持不变 x
  • 使用QQuaternion对Qt Data Visualization中模型进行旋转

    在Data Visualization中 xff0c 三维显示的OBJ需要旋转时使用rotation属性 xff0c 但是该属性传入的值是一个四元数QQuaternion xff0c 直接赋值四元数很复杂 xff0c 因此使用转化的方式获得
  • QML 可拖拽边框和顶点调整大小组件(新增对主窗口支持)

    QML项目开发过程中 xff0c 有时候需要对控件大小和位置 进行人为调整 xff0c 因此设计该组件 该组件鼠标置于边框和顶点位置时鼠标样式对应改变 xff0c 拖动边框可修改该方向组件大小 xff0c 拖动顶点可修改组件处横纵向组件大小
  • QML 地图修改插件源码(五),Map添加自定义地图类型,并动态修改地图类型

    QML的地图Map中提供了属性activeMapType MapType用于设置当前地图的类型 xff0c 以OSM地图插件为例 xff0c OSM地图提供了多种地图类型 xff0c 下面介绍如何修改OSM插件的源码添加需要的地图类型 xf
  • Qt使用QQuaternion对空间矢量QVector3D进行旋转

    空间中的QVector3D既可以代表空间中的点位置 xff0c 也可以表示空间矢量 为什么要对空间矢量进行旋转呢 xff0c 比如有一个空间矢量在空间中代表了镜头前进的方向 xff08 即第一人称模式 xff09 xff0c 初始时该矢量指
  • QML实现双屏显示

    QML程序中需要分别在主屏幕和分屏幕上显示不同的界面内容 xff0c 但又为了不同界面间能够进行数据交互 xff0c 因此使用如下方法实现双屏显示 xff0c 即由主窗口生成第二个窗口 xff0c 将该窗口移动到第二个屏幕上 xff0c 实
  • ubuntu设置默认内核启动的方法

    本文介绍ubuntu设置默认内核启动的方法 参考如下图 xff0c 修改grub文件 xff1a 修改后 xff0c 执行 xff1a sudo update grub amp amp reboot
  • QML自定义的日历控件

    QML中提供了日历的控件Calendar xff0c 但该控件为QtQuick Controls 1中提供的控件 xff0c 因此只能使用QtQuick Controls Styles的方式对该控件进行设置 xff0c 效果如图 xff1a
  • QML地图Map中使用QPainterPath,并显示任意点经纬度位置

    QML地图Map中提供了供绘制图形的组件 xff0c 例如MapPolyline xff0c MapCircle等 xff0c 但是这些组件在绘制复杂轨迹时就显得功能不够全面 xff0c 因此我将QPainterPath在Map中进行使用并
  • QML地图绘制虚线

    QML提供了MapPolyline用于在地图上绘制线段 xff0c 该线段是实线 xff0c 因此我使用Canvas自定义绘制的方式在地图上绘制线段 xff0c 如图 xff1a 鼠标在地图上点击后 xff0c 在点击位置添加图标 xff0
  • QML无边框最大化窗口时遮住了任务栏,程序默认置顶的问题

    在QML窗口使用无边框 xff0c 并且默认程序最大化显示后 xff0c 此时程序显示默认自动变成了全屏显示 xff0c 程序自动遮挡住了系统任务栏 当使用多屏幕显示时 xff0c 切换不同程序 xff0c 该QML程序的界面显示错误 使用
  • 用VScode写C/C++,从下载安装到配置使用

    介绍 编程的过程大致分为编写代码 代码编译 代码执行三步 xff0c vscode可以完成代码编写 xff0c 但是不能进行编译 也就是将代码翻译为计算机可以听懂的话 xff0c MinGW可以完成这个任务 xff0c 二者配合可以实现在v
  • 深度学习训练降低显存指南

    一 小模块API参数inplace设置为True xff08 省一点点 xff09 比如 xff1a Relu 有一个默认参数inplace xff0c 默认设置为False xff0c 当设置为True时 xff0c 计算时的得到的新值不
  • C++工程师学习内容

    C 43 43 是最贴近底层编程语言 在性能方面上 xff0c 有着无可替代的优势特别是对于很多游戏开发公司来说 xff0c C 43 43 尤其适合作为后端服务的开发语言 在一些对于并发性能要求较高的业务上 xff0c C 43 43 也
  • Ubuntu 更新apt出错

    输入sudo apt get update后出现 Err 1 http us archive ubuntu com ubuntu xenial InRelease Temporary failure resolving 39 us arch
  • 使用OpenWrt开发嵌入式Linux(二):先让系统跑起来(使用initramfs)

    安装相关工具 推荐使用ubuntu 16及以上版本 sudo apt install gcc binutils bzip2 flex python perl make diffutils unzip gawk subversion zlib
  • 使用kubeadm从0到1搭建kubernete集群

    目录 概述 安装前提示 安装docker 安装kubeadm 安装kubernete集群master节点 安装 kubeadm kubectl kubelet组件 安装kubernete master节点 安装CNI网络插件 部署集群wor
  • shell基础之变量(2):变量有哪些种类、怎么定义/赋值/取值、不同种类变量的作用域

    通过本文能对shell变量有一个系统性的了解 xff0c 具体的包括 xff1a 变量的种类 xff1a 局部 全局 环境变量变量的定义和操作 xff1a 赋值 取值 取消变量变量的作用域 文章目录 一 变量的种类1 全局变量2 局部变量
  • java 泛型全解 - 绝对最详细

    背景 对于java的泛型我一直属于一知半解的 xff0c 平常真心用的不多 直到阅读 Effect Java 看到很多平常不了解的用法 xff0c 才下定决心 xff0c 需要系统的学习 xff0c 并且记录下来 1 泛型的概述 xff1a
  • Zookeeper数据同步流程

    在服务器启动阶段 xff0c 会进行磁盘数据的恢复 xff0c 完成数据恢复后就会进行Leader选举 一旦选举产生Leader服务器后 xff0c 就立即开始进行集群间的数据同步 xff0c 在整个过程中 xff0c Zookeeper都