博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Zookeeper--数据初始化过程
阅读量:2443 次
发布时间:2019-05-10

本文共 2948 字,大约阅读时间需要 9 分钟。

数据初始化过程

在这里插入图片描述

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

1.初始化FileTxnSnapLog

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

2.初始化ZKDatabase

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

DataTree是ZooKeeper 内存数据的核心模型,简而言之就是一棵树,保存了ZooKeeper上的所有节点信息,在每个ZooKeeper 服务器内部都是单例。在ZKDatabase初始化的时候,DataTree也会进行相应的初始化工作一创建一些ZooKeeper的默认节点,包括/、/zookeeper和/zookeeper/quota三个节点的创建。

除了ZooKeeper的数据节点,在ZKDatabase的初始化阶段还会创建一个用于保存所有客户端会话超时时间的记录器: sessionsWithTimeouts——我 们称之为“会话超时时间记录器”。

3.创建PlayBackListener监听器

PlayBackListener监听器主要用来接收事务应用过程中的回调。在后面读者会看到,在ZooKeeper数据恢复后期,会有一个事务订正的过程,在这个过程中,会回调PlayBackListener监听器来进行对应的数据订正。

4.处理快照文件

完成内存数据库的初始化之后,ZooKeeper就可以开始从磁盘中恢复数据了。在上文中我们已经提到,每一个快照数据文件中都保存了ZooKeeper 服务器近似全量的数据,因此首先从这些快照文件开始加载。

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

一般在ZooKeeper服务器运行一段时间之后,磁盘上都会保留许多个快照文件。另外由于每次数据快照过程中,ZooKeeper都会将全量数据Dump到磁盘快照文件中,因此往往更新时间最晚的那个文件包含了最新的全量数据。那么是否我们只需要这个最新的快照文件就可以了呢?在ZooKeeper的实现中,会获取最新的至多100 个快照文件(如果磁盘上仅存在不到100 个快照文件,那么就获取所有这些快照文件)。

6. 解析快照文件

获取到这至多100个文件之后,ZooKeeper 会开始“逐个”进行解析。每个快照文件都是内存数据序列化到磁盘的二二进制文件,因此在这里需要对其进行反序列化,生成DataTree对象和sessionsWithTimeouts 集合。同时在这个过程中,还会进行文件的checkSum校验以确定快照文件的正确性。

需要注意的一点是,虽然在步骤5中获取到的是100 个快照文件,但其实在这里,的“逐个”解析过程中,如果正确性校验通过的话,那么通常只会解析最新的那个快照文件。换句话说,只有当最新的快照文件不可用的时候,才会逐个进行解析,直到将这100个文件全部解析完。如果将步骤4中获取的所有快照文件都解析完后还是无法成功恢复-一个完整的DataTree和sessionsWithTimeouts,则认为无法从磁盘中加载数据,服务器启动失败。

7.获取最新的ZXID

完成步骤6的操作之后,就已经基于快照文件构建了一个完整的DataTree实例和sess ionsWithTimeouts集合了。此时根据这个快照文件的文件名就可以解析出一个最新的ZXID: zxid_ for_ snap,该ZXID代表了ZooKeeper 开始进行数据快照的时刻。

8.处理事务日志

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

9.获取所有zxid_ for_ snap之后提交的事务

到这里,我们已经获取到了快照数据的最新ZXID。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

epoch是ZooKeeper 中一个非常特别的变量,其字面意思是“纪元、时代”,在ZooKeeper中,epoch 标识了当前Leader周期。每次选举产生一个新的Leader服务器之后,就会生成一个新的epoch。在运行期间集群中机器相互通信的过程中,都会带上这个epoch以确保彼此在同一个Leader周期内。

在完成数据加载后,ZooKeeper会从步骤11中确定的ZXID中解析出事务处理的Leader周期: epochOfZxid。 同时也会从磁盘的currentEpoch 和acceptedEpoch文件中读取出上次记录的最新的epoch值,进行校验。

PlayBackListener

PlayBackListener是一个事务应用监听器,用于在事务应用过程中的回调:每当成功将一条事务日志应用到内存数据库中后,就会调用这个监听器。其接口定义非常简单,只有一个方法:

void onTxnLoaded(TxnDeader hdr, record rec);

用于对单条事务进行处理。在完成步骤2 ZKDatabase的初始化后,ZooKeeper会立即创建一个PlayBackListener监听器,并将其置于FileTxnSnapLog中。在之后的步骤10事务应用过程中,会逐条回调该接口进行事务的二次处理。

PlayBackListener会将这些刚刚被应用到内存数据库中的事务转存到ZKDatabase.committedLog中,以便集群中服务器间进行快速的数据同步。

转载地址:http://uapqb.baihongyu.com/

你可能感兴趣的文章
在React中使用Font Awesome 5
查看>>
React Hooks入门
查看>>
盖茨比乔布斯_用盖茨比快速浏览WordPress站点
查看>>
docker react_10分钟内即可实现具有安全性的React + Docker
查看>>
vue.js表单验证_Vue.js中的模板驱动表单验证
查看>>
软件测试结束标志_使用功能标志进行生产中的测试
查看>>
css网格_在CSS网格中放置,跨度和密度
查看>>
火狐动态调试css_使用Firefox开发工具调试CSS网格
查看>>
服务周期性工作内容_使服务工作者生命周期神秘化
查看>>
响应式屏幕_检测角度的响应式屏幕尺寸
查看>>
vue中使用vuex_使用Vuex在Vue中处理身份验证
查看>>
报纸打字项目_使用打字稿设置节点项目
查看>>
nuxt.js 全局 js_在Nuxt.js应用中实现身份验证
查看>>
具有NgClass和NgStyle的Angular 2+类
查看>>
网络抓取_使用ScrapeStack轻松进行网络抓取
查看>>
koa express_Koa简介-Express的未来
查看>>
github请求超时_在GitHub中创建第一个请求请求
查看>>
JavaScript函数式编程介绍:使用map(),filter()和reduce()进行列表处理
查看>>
gatsby_使用Gatsby,React和Netlify轻松搞定JAM
查看>>
如何在Digital Ocean上托管Node.js应用
查看>>