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

    • 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章 面试考点与设计思想

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

本章定位:ZAB 协议是 ZooKeeper 集群一致性的核心引擎。理解 ZAB 的广播模式和恢复模式,才能真正掌握 ZooKeeper 的数据同步原理。

定义与作用

ZooKeeper Atomic Broadcast(ZAB) 是 ZooKeeper 自研的一致性协议,用于在集群节点间可靠地复制状态变更。

ZAB 协议解决的分布式痛点:

痛点ZAB 的解决方案
多副本数据一致原子广播:事务要么全部节点执行,要么都不执行
Leader 故障崩溃恢复:自动选举新 Leader 并回滚未提交事务
网络分区Quorum 机制:只有多数派存活时继续服务
消息顺序性FIFO 通道 + ZXID 单调递增保证全局顺序

核心原理

两种运行模式

ZAB 协议在两种模式下交替运行:

消息广播模式

广播流程:Leader 提案 → Follower 确认 → Leader 收集多数 ACK → 广播 Commit。只有过半数 Follower ACK 后才会提交,保证一致性。

ZXID 设计

ZXID(ZooKeeper Transaction ID)是 ZAB 协议的核心设计:

ZXID: 64-bit
┌───────────────┬───────────────┐
│  epoch (32bit) │ counter (32bit) │
└───────────────┴───────────────┘
字段含义变化时机
epoch任期号Leader 变更时 +1
counter事务计数器每次写操作 +1

ZXID 全局单调递增,是崩溃恢复时比较事务新旧的依据。

完整示例

示例一:追踪 ZXID 变化

场景说明:通过 zkCli.sh 观察每次写操作的 ZXID 递增。

zkCli.sh -server 127.0.0.1:2181

# 创建节点,观察 czxid 和 mzxid
[zkshell: 0] create /track "step-1"
Created /track
# czxid = mzxid = 0x100000001

[zkshell: 1] set /track "step-2"
# mzxid = 0x100000002(counter 从 1 → 2)

[zkshell: 2] set /track "step-3"
# mzxid = 0x100000003(counter 从 2 → 3)

[zkshell: 3] create /track/child "c1"
# czxid = 0x100000004
# 父节点 pzxid = 0x100000004(最后一个修改子节点的事务)

操作前后对比:

操作ZXIDepochcounter影响
create /track0x1000000010x11czxid=1, mzxid=1
set step-20x1000000020x12mzxid=2, version=1
set step-30x1000000030x13mzxid=3, version=2
create child0x1000000040x14pzxid=4, cversion=1

示例二:观察崩溃恢复后 epoch 变化

场景说明:集群 Leader 宕机后新 Leader epoch 递增。

# Leader(2182 端口)宕机前
zkCli.sh -server 127.0.0.1:2182
[zkshell: 0] get /test
# mzxid = 0x100000010

# 停掉 Leader
bin/zkServer.sh stop conf/zoo-2.cfg

# 等待选举完成(约 10 秒)
# 新 Leader(2181 端口)
zkCli.sh -server 127.0.0.1:2181
[zkshell: 0] create /after-election "new data"
Created /after-election
# czxid = 0x200000001(epoch 从 0x1 → 0x2)

操作前后对比:

时间点当前 Leader最新 ZXIDepoch
Leader 宕机前Server 2 (2182)0x1000000100x1
Leader 宕机后Server 1 (2181)0x2000000010x2(递进)

示例三:Java API 验证原子广播

场景说明:并发写入多个节点,验证事务的原子性和顺序性。

public class ZABDemo {
    public static void main(String[] args) throws Exception {
        CountDownLatch latch = new CountDownLatch(1);

        // 3 个客户端同时写入
        for (int i = 0; i < 3; i++) {
            final int idx = i;
            new Thread(() -> {
                try {
                    ZooKeeper zk = new ZooKeeper(
                        "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183",
                        3000, e -> {});
                    latch.await(); // 同时释放
                    Stat stat = new Stat();
                    zk.getData("/zab-test", false, stat);
                    // 乐观锁更新
                    zk.setData("/zab-test",
                        ("client-" + idx + "-" + stat.getVersion())
                        .getBytes(),
                        stat.getVersion());
                    zk.close();
                } catch (Exception e) {
                    System.out.println("Client " + idx + " failed: "
                            + e.getMessage());
                }
            }).start();
        }

        latch.countDown();
        Thread.sleep(5000);

        // 最终值由 Leader 串行化决定
        ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 3000, e -> {});
        System.out.println("Final: " +
            new String(zk.getData("/zab-test", false, null)));
        zk.close();
    }
}

操作前后对比:

阶段说明
操作前/zab-test 创建,version=0
3 个客户端并发 setData第一个成功的将 version 推进到 1,其余因 version 冲突失败或重试
操作后只有一个客户端成功写入,数据一致

ZAB 协议保证:所有写请求在 Leader 端串行化成 Proposal,按 ZXID 顺序广播。并发请求最终被序列化为全局唯一顺序。

易错场景与面试考点

易错场景

1. 混淆 ZAB 和 Paxos 的 Quorum 概念

ZAB 的 Quorum 是过半数节点成功执行事务,而非 Paxos 的过半数接受提案。ZAB 要求已提交的事务必须被 Quorum 持久化,崩溃恢复时未提交的事务会被回滚。

2. 误解 ZAB 的提交语义

ZAB 采用主备复制模型(Primary-Backup),而非 Multi-Paxos 的全对等模型。Leader 是唯一的主节点,Follower 被动同步。这在实现上简化了状态管理。

3. 认为 ZAB 等于 Paxos

ZAB 不是 Paxos 的直接实现,而是专门为 ZooKeeper 设计的协议。核心区别:

  • ZAB 使用主备模式,Paxos 使用对等节点
  • ZAB 的崩溃恢复有明确的 Leader 激活期
  • ZAB 保证 FIFO 顺序(按 ZXID),Paxos 不保证

面试高频题

Q:ZAB 协议与 Raft 协议的主要异同?

A:

  • 相似:Leader-based、日志复制、Quorum 投票、任期(epoch/term)
  • 不同:ZAB 使用 FIFO 通道 + ZXID,Raft 使用 log index + term;ZAB 的提交不要求日志连续(可乱序到达),Raft 要求严格连续

Q:崩溃恢复时 ZAB 如何保证状态一致?

A:新 Leader 执行以下步骤:

  1. 收集所有 Follower 的最近 ZXID
  2. 确定最大已提交 ZXID(至少一个 Quorum 的 Follower 有此 ZXID)
  3. 通知所有 Follower 截断(Truncate)到该 ZXID
  4. Leader 向 Follower 同步(Snapshot + Diff)到最新状态

Q:ZXID 为何采用 epoch + counter 设计?

A:epoch 解决了 Leader 变更后的序号冲突——即使新 Leader 重置 counter 为 0,由于 epoch 递增,ZXID 仍然全局唯一且递增。同时 ZXID 可直接比较新旧(不需要额外的 term 序列化逻辑)。

小结

要点说明
两种模式消息广播(正常运行)+ 崩溃恢复(Leader 变更)
两阶段提交Proposal → ACK(Quorum) → Commit
ZXIDepoch(32bit) + counter(32bit),全局单调递增
FIFO 通道消息按 ZXID 顺序有序传递
Quorum必须过半数节点参与才能提交事务

ZAB 协议是 ZooKeeper 一致性的基石。下一节深入"一致性保证",从客户端角度理解 ZAB 提供的一致性语义。

下一页
一致性保证