Zookeeper 日志&快照

Zookeeper 日志&快照

一、Zookeeper 日志

Zookeeper 服务器会产生三类日志:事务日志、快照日志和 log4j 日志。
在 zookeeper 默认配置文件 zoo.cfg(可以修改文件名)中有一个配置项 dataDir,该配置项用于配置 zookeeper 快照日志和事务日志的存储地址。在官方提供的默认参考配置文件 zoo_sample.cfg 中,只有 dataDir 配置项。其实在实际应用中,还可以为事务日志专门配置存储地址,配置项名称为 dataLogDir,在 zoo_sample.cfg 中并未体现出来。

在没有 dataLogDir 配置项的时候,zookeeper 默认将事务日志文件和快照日志文件都存储在 dataDir 对应的目录下。* 建议将事务日志(dataLogDir)与快照日志(dataLog)单独配置,因为当 zookeeper 集群进行频繁的数据读写操作是,会产生大量的事务日志信息,将两类日志分开存储会提高系统性能,而且,可以允许将两类日志存在在不同的存储介质上,减少磁盘压力。*

log4j 用于记录 zookeeper 集群服务器运行日志,该日志的配置地址在 conf/ 目录下的 log4j.properties 文件中,该文件中有一个配置项为 zookeeper.log.dir=.,表示 log4j 日志文件在与执行程序(zkServer.sh)在同一目录下。当执行 zkServer.sh 时,在该文件夹下会产生 zookeeper.out 日志文件。

二、事务日志

事务日志指 zookeeper 系统在正常运行过程中,针对所有的更新操作,在返回客户端 “更新成功” 的响应前,zookeeper 会保证已经将本次更新操作的事务日志已经写到磁盘上,只有这样,整个更新操作才会生效。
根据上文所述,可以通过 zoo.cfg 文件中的 dataLogDir 配置项找到事物日志存储地点:
datalog/ 目录下存在一个文件夹 version-2,该文件夹中保存着事物日志文件:
日志文件的命名规则为 log.,文件大小为 64MB 表示写入该日志的第一个事务的 ID,十六进制表示。

三、事务日志可视化

Zookeeper 的事务日志为二进制文件,不能通过 vim 等工具直接访问。其实可以通过 zookeeper 自带的 jar 包读取事务日志文件。
首先将 libs 中的 slf4j-api-1.6.1.jar 文件和 zookeeper 根目录下的 zookeeper-3.4.9.jar 文件复制到临时文件夹 tmplibs 中,然后执行如下命令:

java -classpath .:slf4j-api-1.7.25.jar:zookeeper-3.4.14.jar org.apache.zookeeper.server.LogFormatter /opt/zookeeper/transactionLog/version-2/log.504e25800 > a.txt

其中:/opt/zookeeper/transactionLog/version-2/log.4 是日志路径下的日志文件。
命令是在 zookeeper 的 bin 目录下执行的,因此使用.:lib。
zookeeper-3.4.14.jar 表示我所使用的 zk 版本是 3.4.12 版本。

四、快照日志

Zookeeper 的数据在内存中是以树形结构进行存储的,而快照就是每隔一段时间就会把整个 DataTree 的数据序列化后存储在磁盘中,这就是 zookeeper 的快照文件。
zookeeper 快照日志的存储路径同样可以在 zoo.cfg 中查看,如上文截图所示。访问 dataDir 路径可以看到 version-2 文件夹:
从截图中可以看出,zookeeper 快照文件的命名规则为 snapshot.**,其中 ** 表示 zookeeper 触发快照的那个瞬间,提交的最后一个事务的 ID。

五、日志清理

在 zookeeper 3.4.0 以后,zookeeper 提供了自动清理 snapshot 和事务日志功能,通过配置 zoo.cfg 下的。
autopurge.snapRetainCountautopurge.purgeInterval 这两个参数实现日志文件的定时清理:

  • autopurge.snapRetainCount 这个参数指定了需要保留的文件数目,默认保留 3 个。
  • autopurge.purgeInterval 这个参数指定了清理频率,单位是小时,需要填写一个 1 或者更大的数据,默认 0 表示不开启自动清理功能。

六、事务日志和快照日志的关联

ZooKeeper 集群中的每个服务器节点每次接收到写操作请求时,都会先将这次请求发送给 leader,leader 将这次写操作转换为带有状态的事务,然后 leader 会对这次写操作广播出去以便进行协调。当协调通过 (大多数节点允许这次写) 后,leader 通知所有的服务器节点,让它们将这次写操作应用到内存数据库中,并将其记录到事务日志中。当事务日志记录的次数达到一定数量后 (默认 10W 次),就会将内存数据库序列化一次,使其持久化保存到磁盘上,序列化后的文件称为 "快照文件"。每次拍快照都会生成新的事务日志。有了事务日志和快照,就可以让任意节点恢复到任意时间点 (只要没有清理事务日志和快照)。

事务日志和快照日志可用于 zookeeper 恢复数据,假设 t1 时刻保存了快照日志,t1 到 t2 时刻保存了事务日志 (这段时间内没有再新增快照),那么 t2 时刻重启 zookeeper,数据不会丢失

快照相当于将当前的 zookeeper 状态记录了下来,保留了快照之后,该快照之前创建的快照和事务日志丢失是没有影响的。

如果 t1 时刻保存了快照,但是 t1 到 t2 的事务日志丢失并且后面也没有快照,那么 t1 到 t2 之间的数据无法恢复,只能恢复到 t1 时刻的状态。

评论

暂无

添加新评论