Zookeeper--数据快照snapshot
数据快照snapshot数据快照是ZooKeeper数据存储中另–个非常核心的运行机制。顾名思义,数据快照用来记录ZooKeeper服务器上某一个时刻的全量内存数据内容,并将其写入到指定的磁盘文件中。文件存储:快照文件存储在dataDir属性配置的目录下。假定我们确定dataDi r为/home/admin/zkData/zk_ data, 那么ZooKeeper在运行过程中会在该目录下建立一个名
数据快照snapshot
数据快照是ZooKeeper数据存储中另–个非常核心的运行机制。顾名思义,数据快照用来记录ZooKeeper服务器上某一个时刻的全量内存数据内容,并将其写入到指定的磁盘文件中。
文件存储:
快照文件存储在dataDir属性配置的目录下。
假定我们确定dataDi r为/home/admin/zkData/zk_ data, 那么ZooKeeper在运行过程中会在该目录下建立一个名为version-2 的目录,该目录确定了当前ZooKeeper使用的快照数据格式版本号。运行一段时间后,我们可以发现在/home/admin/zkData/zk data/version-2 目录下会生成类似下面这样的文件:
和事务日志文件的命名规则一致,快照数据文件也是使用ZXID的十六进制表示来作为文件名后缀,该后缀标识了本次数据快照开始时刻的服务器最新ZXID。这个十六进制的文件后缀非常重要,在数据恢复阶段,ZooKeeper会根据该ZXID来确定数据恢复的起始点。
和事务日志文件不同的是,ZooKeeper的快照数据文件没有采用“预分配”机制,因此不会像事务日志文件那样内容中可能包含大量的“0”。每个快照数据文件中的所有内容都是有效的,因此该文件的大小在一定程度上能够反映当前ZooKeeper内存中全量数据的大小。
存储格式:
ZooKeeper也提供了一套简易的快照数据格式化工具org.apache.zookeeper.server.SnapshotFormatter,用于将这个默认的快照数据文件转换成可视化的数据内容,使用方法如下:
//要保证如下这两包jar包存在
java -classpath .:slf4j-api-1.7.25.jar:zookeeper-3.4.14.jar org.apache.zookeeper.server.SnapshotFormatter version-2/快照文件
得到一个类似如下的结果:
之前的二进制形式的文件内容已经被格式化输出了:SnapshotFormatter会将ZooKeeper.上的数据节点逐个依次输出,但是需要注意的一点是,这里输出的仅仅是每个数据节点的元信息,并没有输出每个节点的数据内容,但这已经对运维非常有帮助了。
数据快照:
FileSnap负责维护快照数据对外的接口,包括快照数据的写入和读取等。我们首先来看数据的写入过程一一将内存数据库写入快照数据文件中其实是一个序列化过程。
针对客户端的每一次事务操作, ZooKeeper都会将它们记录到事务日志中,当然,ZooKeeper同时也会将数据变更应用到内存数据库中。另外,ZooKeeper会在进行若干次事务日志记录之后,将内存数据库的全量数据Dump到本地文件中,这个过程就是数据快照。可以使用snapCount参数来配置每次数据快照之间的事务操作次数,即ZooKeeper会在snapCount次事务日志记录后进行一个数据快照。
-
确定是否需要进行数据快照
每进行一次事务日志记录之后,ZooKeeper都会检测当前是否需要进行数据快照。理论_上进行snapCount次事务操作后就会开始数据快照,但是考虑到数据快照对于ZooKeeper所在机器的整体性能的影响,需要尽量避免ZooKeeper集群中的所有机器在同一时刻进行数据快照。因此ZooKeeper在具体的实现中,并不是严格地按照这个策略执行的,而是采取“过半随机”策略,即符合如下条件就进行数据快照:logCount> (snapCount / 2 + randRoll)
其中logCount 代表了当前已经记录的事务日志数量,randRoll 为1 ~ snapCount/2之间的随机数,因此上面的条件就相当于:如果我们配置的snapCount 值为默认的100000,那么ZooKeeper会在50000 ~ 100000次事务日志记录后进行一次数据快照。 -
切换事务日志文件
满足上述条件之后,ZooKeeper 就要开始进行数据快照了。首先是进行事务日志文件的切换。所谓的事务日志文件切换是指当前的事务日志已经“写满”(已经写入了snapCount个事务日志),需要重新创建一个新的事务日志。 -
创建数据快照异步线程
为了保证数据快照过程不影响ZooKeeper的主流程,这里需要创建一个单独的异步线程来进行数据快照。 -
获取全量数据和会话信息
数据快照本质上就是将内存中的所有数据节点信息(DataTree) 和会话信息保存到本地磁盘中去。因此这里会先从ZKDatabase中获取到DataTree和会话信息。 -
生成快照数据文件名
在“文件存储”部分,我们已经提到快照数据文件名的命名规则。在这一步中,ZooKeeper会根据当前已提交的最大ZXID来生成数据快照文件名。 -
数据序列化
接下来就开始真正的数据序列化了。在序列化时,首先会序列化文件头信息,这里的文件头和事务日志中的一致,同样也包含了魔数、版本号和dbid信息。然后再对会话信息和DataTree分别进行序列化,同时生成一个Checksum, 一并写入快照数据文件中去。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)