ZooKeeper事务日志和快照

本文详细解析了ZooKeeper中的两种关键日志——事务日志和系统日志,以及快照机制。阐述了日志和快照的生成过程、配置项及其作用,包括dataDir、dataLogDir、preAllocSize、snapCount等,同时介绍了事务日志的命名规则和查看方法,以及系统日志的默认输出路径和配置。

ZooKeeper有两种日志、一种快照。日志分为事务日志和ZooKeeper运行时的系统日志。

1.事务日志和快照

ZooKeeper集群中的每个服务器节点每次接收到写操作请求时,都会先将这次请求发送给leader,leader将这次写操作转换为带有状态的事务,然后leader会对这次写操作广播出去以便进行协调。当协调通过(大多数节点允许这次写)后,leader通知所有的服务器节点,让它们将这次写操作应用到内存数据库中,并将其记录到事务日志中。

当事务日志记录的次数达到一定数量后(默认10W次),就会将内存数据库序列化一次,使其持久化保存到磁盘上,序列化后的文件称为"快照文件"。每次拍快照都会生成新的事务日志。

有了事务日志和快照,就可以让任意节点恢复到任意时间点(只要没有清理事务日志和快照)。

1.1 事务日志和快照相关的配置项

  • dataDir
    ZooKeeper的数据目录,主要目的是存储内存数据库序列化后的快照路径。如果没有配置事务日志(即dataLogDir配置项)的路径,那么ZooKeeper的事务日志也存放在数据目录中。

  • dataLogDir
    指定事务日志的存放目录。事务日志对ZooKeeper的影响非常大,强烈建议事务日志目录和数据目录分开,不要将事务日志记录在数据目录(主要用来存放内存数据库快照)下。

  • preAllocSize
    为事务日志预先开辟磁盘空间。默认是64M,意味着每个事务日志大小就是64M(可以去事务日志目录中看一下,每个事务日志只要被创建出来,就是64M)。如果ZooKeeper产生快照频率较大,可以考虑减小这个参数,因为每次快照后都会切换到新的事务日志,但前面的64M根本就没写完。(见snapCount配置项)

  • snapCount
    ZooKeeper使用事务日志和快照来持久化每个事务(注意是日志先写)。该配置项指定ZooKeeper在将内存数据库序列化为快照之前,需要先写多少次事务日志。也就是说,每写几次事务日志,就快照一次。默认值为100000。为了防止所有的ZooKeeper服务器节点同时生成快照(一般情况下,所有实例的配置文件是完全相同的),当某节点的先写事务数量在(snapCount/2+1,snapCount)范围内时(挑选一个随机值),这个值就是该节点拍快照的时机。

  • autopurge.snapRetainCount
    该配置项指定开启了ZooKeeper的自动清理功能后(见下一个配置项),每次自动清理时要保留的版本数量。默认值为3,最小值也为3。它表示在自动清理时,会保留最近3个快照以及这3个快照对应的事务日志。其它的所有快照和日志都清理。

  • autopurge.purgeInterval
    指定触发自动清理功能的时间间隔,单位为小时,值为大于或等于1的整数,默认值为0,表示不开启自动清理功能。

1.2 事务日志和快照的命名规则

在ZooKeeper集群启动后,当第一个客户端连接到某个服务器节点时,会创建一个会话,这个会话也是事务,于是创建第一个事务日志,一般名为log.100000001,这里的100000001是这次会话的事务id(zxid)。之后的事务都将写入到这个文件中,直到拍下一个快照。

如果是事务ZXID5触发的拍快照,那么快照名就是snapshot.ZXID5,拍完后,下一个事务的ID就是ZXID6,于是新的事务日志名为log.ZXID6。

1.3 查看事务日志

事务日志是一个二进制文件,无法直接查看。好在ZooKeeper提供了一个LogFormatter工具类。

假设ZooKeeper安装目录为/usr/local/zookeeper,那么可以通过下面的方法来查看事务日志log.100000001中的内容。

java -cp /usr/local/zookeeper/zookeeper-3.4.12.jar:/usr/local/zookeeper/lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.LogFormatter /usr/local/zookeeper/data/version-2/log.100000001

以下是一个事务日志的内容示例。

1.4 自动清理功能

从ZooKeeper 3.4.0开始,ZooKeeper提供了自动清理事务日志和快照的功能,见事务日志和快照相关的配置项

此外,还提供了一个脚本zkCleanup.sh,它也用来清理事务日志和快照。但比较少用。

有时也会写定时任务脚本,来删除定时、定点的事务日志和快照数据。

2.ZooKeeper系统的系统日志

ZooKeeper使用log4j(log for java)来记录系统日志。默认情况下,系统日志文件为ZooKeeper安装目录下的zookeeper.out,这是由log4j的配置文件决定的。(实际上,zkEnv.sh和zkServer.sh中也设置了日志的路径,见下文)。

ZooKeeper使用的log4j的配置文件为$ZOOKEEPER_HOME/conf/log4j.properties

[root@s1 zk]# cat conf/log4j.properties
# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=.               # 日志目录
zookeeper.log.file=zookeeper.log  # 日志文件名称
zookeeper.log.threshold=DEBUG
zookeeper.tracelog.dir=.
zookeeper.tracelog.file=zookeeper_trace.log
.....省略.......

log4j.properties中没有指定zookeeper.out啊?但为什么会输出到zookeeper.out中呢?这是因为zkServer.sh中指定了这个文件。以下是zkServer.sh中和zookeeper.out相关的内容:

.........省略.............

_ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper.out"

case $1 in
start)
    echo  -n "Starting zookeeper ... "

    .........省略.............

    nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
    -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &

.........省略.............

可以看到,在zkServer.sh的start选项中,使用nohup启动ZooKeeper,并将日志输出到"$ZOO_LOG_DIR/zookeeper.out"中。

一般来说,没有特殊需求,没必要去改log4j日志配置。要改的话,记得把log4j.properties和zkEnv.sh和zkServer.sh中相关的内容都修改掉。

 

转自 https://www.cnblogs.com/f-ck-need-u/p/9236954.html

ZooKeeper 是一个分布式协调服务,其核心特性之一是高可靠性数据一致性。为了实现这一目标,ZooKeeper 采用快照(Snapshot)事务日志(Transaction Log)机制来确保数据的持久化恢复能力。 ### 快照(Snapshot) 快照是对 ZooKeeper 内存数据库的一个完整备份。每当 ZooKeeper 完成一定数量的事务操作后,会触发一次快照操作,将当前所有节点的状态以文件的形式写入磁盘。这个过程可以减少恢复时需要处理的事务日志数量,从而加快恢复速度。快照的生成频率可以通过配置参数 `snapCount` 进行调整,默认值为 **100000** 次事务操作[^2]。 快照的作用主要体现在以下几个方面: - **快速恢复**:在系统重启或故障恢复时,ZooKeeper 可以通过加载最新的快照快速恢复到某个一致性的状态。 - **降低存储压力**:相比于仅依赖事务日志进行恢复,快照减少了需要回放的日志数量,降低了存储恢复的时间成本。 ### 事务日志(Transaction Log) 事务日志记录了所有对 ZooKeeper 数据树进行修改的操作,例如创建节点、删除节点、更新节点数据等。每个事务日志条目都包含一个唯一的事务 ID(ZXID),用于标识该事务的顺序[^1]。 事务日志的主要作用包括: - **数据持久化**:确保即使在系统崩溃的情况下,所有已经提交的事务也能被保留下来。 - **恢复依据**:在 ZooKeeper 启动时,系统会先加载最新的快照,然后根据事务日志中记录的未包含在快照中的事务进行重放,以恢复到最近的一致性状态。 ### 工作原理 ZooKeeper快照事务日志协同工作,具体流程如下: 1. **事务日志写入**:每次对 ZooKeeper 数据进行修改时,都会首先将该操作记录到事务日志中,并分配一个递增的 ZXID。 2. **快照生成**:当完成指定次数(由 `snapCount` 控制)的事务操作后,ZooKeeper 会生成一个新的快照文件,保存当前内存中所有节点的状态。 3. **日志快照结合**:快照生成后,后续的事务日志仍然继续写入当前的日志文件,直到下一个快照生成周期到来。如果当前日志文件已满,则会切换到新的日志文件。 4. **恢复过程**:在 ZooKeeper 启动时,首先查找最新的快照文件,并找到该快照对应的 ZXID。随后读取所有事务 ID 大于该 ZXID 的事务日志,进行重放,以重建完整的数据状态。 ### 配置与存储路径 ZooKeeper快照事务日志的存储路径可以通过以下配置项进行设置: - `dataDir`:用于指定快照文件事务日志的默认存储目录。 - `dataLogDir`:如果设置了该配置项,则事务日志会被单独存储在该目录下,而快照文件仍保留在 `dataDir` 所指定的目录中[^3]。 这种分离存储的方式有助于提高性能,尤其是在高并发写入场景下,可以避免磁盘 I/O 瓶颈。 ### 查看快照内容 ZooKeeper 提供了工具类 `SnapshotFormatter` 来解析快照文件的内容。例如,可以通过以下命令将快照文件的内容输出到日志文件中: ```bash java -cp .:/tmp/zookeeper-3.5.5.jar:/tmp/zookeeper-jute-3.5.5.jar:/tmp/log4j-1.2.17.jar:/tmp/slf4j-api-1.7.25.jar:/tmp/slf4j-log4j12-1.7.25.jar org.apache.zookeeper.server.SnapshotFormatter /tmp/zookeeper/version-2/snapshot.0 > /tmp/zksnapshot.log ``` 此命令使用了 ZooKeeper 的 JAR 包及相关依赖库,调用 `SnapshotFormatter` 类来格式化输出快照内容[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值