11.6.5 备份与恢复流程

本节说明 ZooKeeper 数据的备份与恢复流程,包含快照与事务日志的管理、手工与自动化策略、单机与集群级恢复以及验证方法。目标是确保数据一致性、最小化停机与可追溯的运维操作。

备份对象与存储位置#

ZooKeeper 数据由两部分组成:快照(snapshot)与事务日志(log),二者共同保证可恢复性。常见路径:
- dataDir:快照文件与部分事务日志
- dataLogDir:事务日志(推荐独立磁盘)
- myid:节点标识文件
- zoo.cfg/zoo.cfg.dynamic:配置与动态集群成员信息

示例配置(确认路径):

# /opt/zookeeper/conf/zoo.cfg
dataDir=/data/zk/data
dataLogDir=/data/zk/log
autopurge.snapRetainCount=10
autopurge.purgeInterval=1

建议将配置文件、myiddataDirdataLogDir 与 JDK/启动脚本一并纳入备份范围,便于快速恢复节点。

原理草图:快照与日志恢复链路#

文章图片

备份策略与频率#

  • 全量备份:定期拷贝 dataDirdataLogDir,适用于小集群或变更较少场景。
  • 增量备份:以事务日志为增量,配合周期性快照;需保证日志连续。
  • 策略建议:每日全量、小时级别日志增量;保留最近 7–30 天。
  • 一致性建议:备份前触发强制快照或确保服务静默期,减少日志重放量。

手工备份流程(单节点/节点级)#

1. 状态确认与快照准备#

确认节点角色与健康:

# 查看角色
/opt/zookeeper/bin/zkServer.sh status
# 预期输出:Mode: follower/leader

触发轻量事务以促使快照生成(可选):

/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 <<'EOF'
create /backup_ping "ts-$(date +%F_%T)"
delete /backup_ping
quit
EOF

2. 停止服务并执行备份#

systemctl stop zookeeper

# 备份目录结构(示例)
tar -C / -czf /backup/zk_full_$(date +%F).tgz \
  data/zk/data data/zk/log opt/zookeeper/conf/zoo.cfg \
  opt/zookeeper/conf/zoo.cfg.dynamic data/zk/data/myid

3. 启动与验证#

systemctl start zookeeper
echo ruok | nc 127.0.0.1 2181
# 预期输出:imok

在线备份建议使用 LVM/存储快照,避免文件不一致。

集群级备份建议#

  • 不需要所有节点同时备份:选择任意一台状态正常的 Follower 备份即可。
  • 避免备份正在频繁变更的节点:优先选择延迟小、日志压力低的节点。
  • 记录集群版本与配置:备份 zoo.cfg.dynamic,确保恢复时成员一致。

示例:选择 Follower 并打印模式

for h in zk1 zk2 zk3; do
  echo "== $h =="; ssh $h "echo stat | nc 127.0.0.1 2181 | grep Mode"
done

恢复流程(单节点)#

1. 停止服务并清理#

systemctl stop zookeeper
mv /data/zk/data /data/zk/data.bak.$(date +%F)
mv /data/zk/log  /data/zk/log.bak.$(date +%F)

2. 解压恢复与校验#

tar -C / -xzf /backup/zk_full_2024-01-10.tgz
cat /data/zk/data/myid
# 确保与 zoo.cfg 或 zoo.cfg.dynamic 中 server.X 的 X 一致

3. 启动并检查恢复日志#

systemctl start zookeeper
# 关键日志:Loaded snapshot / Recovered
tail -n 50 /data/zk/log/zookeeper.out

4. 验证集群状态#

echo stat | nc 127.0.0.1 2181 | egrep 'Mode|Zxid'
/opt/zookeeper/bin/zkServer.sh status

集群恢复与重建#

  • 部分节点故障:逐台恢复,确保多数节点在线。
  • 多数节点不可用
  • 从最新一致备份恢复至少半数以上节点;
  • 保持 zxid 连续,避免不一致选主。
  • 重建集群
  • 新集群需使用一致快照与日志;
  • 修改 zoo.cfg.dynamic 后配合滚动启动。

滚动恢复示例(3 节点):

for h in zk1 zk2 zk3; do
  ssh $h "systemctl stop zookeeper"
  ssh $h "tar -C / -xzf /backup/zk_full_2024-01-10.tgz"
  ssh $h "systemctl start zookeeper"
  sleep 5
  ssh $h "echo ruok | nc 127.0.0.1 2181"
done

常见问题与处理(含命令)#

  • 日志损坏:删除损坏日志文件,允许从快照恢复(可能丢失部分事务)。
    bash # 仅在确认日志损坏时处理 ls -l /data/zk/log rm -f /data/zk/log/log.0000000000001234
  • 快照过旧:回放日志耗时长;建议缩短快照周期。
    ini # zoo.cfg snapCount=100000
  • 节点起不来:检查 myidserver.X 配置、权限与磁盘空间。
    bash cat /data/zk/data/myid grep -E '^server\.' /opt/zookeeper/conf/zoo.cfg df -h /data/zk
  • 数据不一致:确认恢复来源唯一,避免跨节点混合数据。
    bash echo stat | nc 127.0.0.1 2181 | grep Zxid

自动化备份脚本示例#

#!/usr/bin/env bash
# /usr/local/bin/zk_backup.sh
set -euo pipefail

BACKUP_DIR=/backup/zk
DATE=$(date +%F_%H%M)
CONF=/opt/zookeeper/conf

mkdir -p "${BACKUP_DIR}"
tar -C / -czf "${BACKUP_DIR}/zk_full_${DATE}.tgz" \
  data/zk/data data/zk/log \
  ${CONF}/zoo.cfg ${CONF}/zoo.cfg.dynamic

# 校验
sha256sum "${BACKUP_DIR}/zk_full_${DATE}.tgz" \
  > "${BACKUP_DIR}/zk_full_${DATE}.sha256"

# 清理 15 天前备份
find "${BACKUP_DIR}" -type f -mtime +15 -delete

建议配合定时任务:

# 每天 02:00 执行
0 2 * * * /usr/local/bin/zk_backup.sh >> /var/log/zk_backup.log 2>&1

验证与演练#

  • 定期进行恢复演练,验证流程与时长。
  • 关键验证点:
  • 集群状态为 follower/leader 正常
  • 业务 znode 存在且版本号符合预期
  • 事务日志回放无异常报错

演练步骤示例:

# 1) 备份
/usr/local/bin/zk_backup.sh

# 2) 恢复到测试节点
systemctl stop zookeeper
tar -C / -xzf /backup/zk/zk_full_2024-01-10_0200.tgz
systemctl start zookeeper

# 3) 验证关键路径
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 <<'EOF'
ls /
get /config
quit
EOF

练习与作业#

  1. 在测试集群中完成一次 Follower 节点的全量备份,并验证 sha256 完整性。
  2. 人为删除一段日志文件,观察恢复时的日志行为并记录影响。
  3. 编写脚本仅备份 dataDirdataLogDir,并在恢复后校验 zxid 是否与备份前一致。