乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • ZooKeeper 学习路径
  • 第1章 分布式协调与ZooKeeper概述

    • ZooKeeper 概述
  • 第2章 单机与集群搭建

    • 配置参数详解
    • 集群搭建
  • 第3章 数据模型与ZNode

    • ZNode 详解
    • 节点类型对比
    • 顺序节点
    • ACL 权限控制
  • 第4章 会话与Watcher机制

    • 会话机制
    • Watcher 机制
  • 第5章 ZAB协议与一致性保证

    • ZAB 协议
    • 一致性保证
    • 数据同步
  • 第6章 Leader选举

    • Leader 选举
  • 第7章 典型应用:分布式锁

    • 分布式锁
  • 第8章 典型应用:配置中心与命名服务

    • 配置中心
    • 命名服务
  • 第9章 客户端编程基础(Java原生API)

    • Java 原生 API 编程
  • 第10章 运维与监控

    • 四字命令
    • 监控体系
  • 第11章 面试考点与设计思想

    • 设计思想
    • 面试考点汇编

本章定位:理解 ZooKeeper 如何在节点宕机重启后恢复数据,以及新节点如何从 Leader 同步完整状态。

定义与作用

数据同步是 ZooKeeper 集群保证数据一致性的关键机制。它解决两个核心问题:

场景同步解决什么
Follower 宕机重启从 Leader 获取宕机期间错过的事务
新节点加入集群从 Leader 获取全量数据
Leader 宕机恢复从本地 Snapshot + 事务日志启动,再与 Follower 对齐

同步依赖两种持久化数据:

数据文件内容
Snapshot(快照)snapshot.<lastZXID>某个时间点的内存全量数据
Transaction Log(事务日志)log.<firstZXID>每次写操作的串行记录

核心原理

同步流程

四种同步类型:SNAP(全量快照同步)、DIFF(增量事务同步)、TRUNC(截断回滚)、TRUNC+DIFF(截断 + 增量)。

快照触发机制

完整示例

示例一:观察 Snapshot 和事务日志

场景说明:查看 dataDir 下的实际文件,理解快照和日志的对应关系。

ls /tmp/zk-data/1/version-2/

# 输出:
log.1          # 事务日志,记录 ZXID 范围 [1, xxx]
snapshot.0     # 初始快照(空状态)
snapshot.100   # ZXID=100 时的快照
# 使用 ZooKeeper 自带的工具查看快照
java -cp zookeeper-3.7.0.jar:lib/* org.apache.zookeeper.server.SnapshotFormatter \
  /tmp/zk-data/1/version-2/snapshot.100

# 输出:
# /zookeeper/config
# /zookeeper/quota
# /app/config = port=8080
# /app/services (子节点:order-service-1)
# ...
# SessionDetails:
# 0x1000000001: timeout=30000

操作前后对比:

文件含义用途
snapshot.0初始空快照服务启动基准
snapshot.100ZXID=100 时内存状态快速恢复到 ZXID=100
log.1 ~ log.101事务日志区间从 ZXID=100 增量恢复到 ZXID=101

示例二:数据恢复验证

场景说明:模拟 Follower 宕机后重启,验证数据不丢失。

# 1. 在集群中写入数据
zkCli.sh -server 127.0.0.1:2182  # Leader
[zkshell: 0] create /recovery-test "before-crash"
Created /recovery-test

# 2. Follower 宕机
bin/zkServer.sh stop conf/zoo-3.cfg

# 3. 继续写入(Leader 和其他 Follower)
[zkshell: 0] create /recovery-test/node1 "after-crash"
Created /recovery-test/node1

# 4. Follower 重启
bin/zkServer.sh start conf/zoo-3.cfg
# 日志显示:
# USING SNAPSHOT snapshot.100
# FOLLOWING - LEADER ELECTION TOOK - 50 MS
# SYNCING WITH LEADER

# 5. Follower 恢复后验证
zkCli.sh -server 127.0.0.1:2183
[zkshell: 0] ls /recovery-test
[node1]
# 宕机期间的数据已同步!

操作前后对比:

节点操作前宕机期间变化重启后
Server 3 (2183)有 /recovery-test下线有 /recovery-test/node1
恢复方式——Snapshot + DIFF 增量同步

示例三:强制生成 Snapshot

场景说明:通过四字命令或 API 手动触发快照。

# 方法一:四字命令
echo "srst" | nc 127.0.0.1 2181
# 输出:Snapshot taken

# 方法二:JMX
# 通过 jconsole 连接,执行 MBean: org.apache.ZooKeeperService
# 调用 takeSnapshot()

执行前后对比:

时间点Snapshot 文件说明
SRST 前snapshot.100最近一次自动快照
SRST 后snapshot.150(新)手动触发即时快照

手动触发快照可在以下场景使用:备份前确保快照最新;大事务量后手动创建恢复点;运维窗口下的预操作。

易错场景与面试考点

易错场景

1. 事务日志磁盘满

当磁盘满时,事务日志无法写入,Leader 会停止接受写请求并 Crash。现象:

java.io.IOException: No space left on device

预防:配置 autopurge 自动清理,监控磁盘使用率。

2. dataDir 和 dataLogDir 放在同一块磁盘

快照写入(随机 I/O)和事务日志写入(顺序 I/O)相互干扰,导致 fsync 延迟增大,整体写性能下降。

3. SNAP 同步的时空代价

新节点加入集群或落后太多时触发全量 SNAP 同步。数据量大时可能占用数 GB 网络带宽和数十分钟时间。生产环境应避免频繁的 SNAP 同步(通过合理配置 snapCount 和保持节点稳定)。

面试高频题

Q:Snapshot 和事务日志的关系?

A:Snapshot 是某个 ZXID 时刻内存状态的完整镜像。事务日志记录了 Snapshot 之后的增量事务。重启时:

  1. 加载最近 Snapshot(快速恢复主体状态)
  2. 重放事务日志(增量恢复到最终状态)

这种设计平衡了恢复速度和存储开销。

Q:DIFF 和 SNAP 同步的触发条件?

A:Leader 根据 Follower 上报的最新 ZXID 判断:

  • ZXID 在 Leader 事务日志范围内 → DIFF 增量同步(发送缺失的事务)
  • ZXID 不在范围内(太老,日志已清理) → SNAP 全量同步
  • ZXID 大于 Leader → TRUNC 截断(说明 Follower 有未提交事务需回滚)

Q:什么时候需要 TRUNC 截断?

A:Leader 宕机时可能有部分 Proposal 已发送但未 Commit。新 Leader 的 ZXID 可能小于某些 Follower 的 ZXID,此时需要 Follower 截断(删除)这些未提交的事务。

小结

要点说明
两种持久化Snapshot(全量快照)+ Transaction Log(增量日志)
三种同步方式SNAP(全量)、DIFF(增量)、TRUNC(截断)
snapCount控制快照触发频率
autopurge自动清理旧快照和日志
恢复流程加载 Snapshot → 重放日志 → 与 Leader 对齐

数据同步是 ZAB 协议崩溃恢复的具体实现。下一章进入 Leader 选举,理解集群如何选出主节点。

上一页
一致性保证