ZAB协议:如何实现操作的顺序性?

云计算 分布式
ZAB 协议通过 全局有序的 zxid 和 两阶段提交机制,实现了分布式系统中事务的全局有序性。这种设计确保了 Zookeeper 能够在复杂的分布式环境中,提供一致性和高可用性。​

今天我们深入剖析 Zookeeper Atomic Broadcast(ZAB)协议,特别聚焦于 “如何实现操作的顺序性” 这个核心问题。ZAB 协议是 Zookeeper 保证分布式数据一致性的重要基础,它解决了 Paxos 在操作顺序性上的天然不足,使得 Zookeeper 能够在分布式场景中稳定地提供一致性和高可用性。

本文将从以下四个方面展开:

  1. 为什么 Multi-Paxos 无法保证操作的顺序性?
  2. ZAB 协议如何保证操作的顺序性?
  3. 核心流程与源码解析
  4. 关键实现细节与 Java 源码示例

一、为什么 Multi-Paxos 无法保证操作的顺序性?

1.1 Multi-Paxos 简述

Multi-Paxos 是 Paxos 算法的扩展,解决了单轮 Paxos 只能处理一个提案的问题。它通过选举一个主节点(Leader),由主节点发起多轮 Paxos 协议,确保所有副本达成一致性。

1.2 顺序性问题

虽然 Multi-Paxos 能够确保每个提案(Proposal)达成一致,但它并不关心提案之间的顺序。比如:

  • 请求 A 和请求 B 可能被不同节点在不同时间接受。
  • Multi-Paxos 无法强制所有节点按照统一的顺序处理 A 和 B。

1.3 ZAB 协议的引入

为了在分布式系统中提供严格的操作顺序性,Zookeeper 设计了 ZAB 协议,它在 Paxos 的基础上增加了 事务 ID(zxid) 和 广播日志(Broadcast Log),确保所有操作按照统一的顺序被处理。

二、ZAB 协议如何保证操作的顺序性?

2.1 核心概念

1. 事务 ID(zxid)

  • 每个事务都有一个唯一的 zxid(Zookeeper Transaction ID)。
  • zxid 是一个64位的数字:前32位是 epoch(领导周期),后32位是 自增计数器。
  • zxid 的有序性确保了所有节点按照相同的顺序处理事务。

2. 广播日志(Broadcast Log)

  • Leader 将所有的写请求转化为 Proposal(提议),并以广播的方式发送给所有的 Follower。
  • 每个 Follower 接收到 Proposal 后,都会按照 zxid 的顺序 进行记录和提交。

3. 两阶段提交

ZAB 协议在 Leader 和 Follower 之间采用了两阶段提交机制:

  • 阶段1:数据广播(Proposal Broadcasting)
  • 阶段2:确认提交(Commit Confirmation)

只有当过半节点确认 Proposal 后,Leader 才会提交该事务。

2.2 操作顺序性的实现

1. Leader 分配有序 zxid

每次 Leader 处理一个客户端的写请求时,它都会分配一个全局有序的 zxid。

2. Proposal 广播

Leader 将事务转化为 Proposal,并按 zxid 顺序向所有 Follower 广播。

3. Follower 日志追加

Follower 接收到 Proposal 后,先将其追加到本地日志中,但暂不提交。

4. Leader 收到过半确认

Leader 收到过半 Follower 的 ACK 后,向所有节点发送 COMMIT 命令。

5. Follower 提交

Follower 接收到 COMMIT 命令后,按照 zxid 的顺序提交事务。

三、核心流程与源码解析

接下来我们将通过 Java 源码示例,剖析 ZAB 协议如何实现操作顺序性。

3.1 Leader 生成 zxid

Leader 在处理请求时生成全局唯一的 zxid。

public class Leader {
    private long epoch = 0; // 当前领导纪元
    private long counter = 0; // zxid 计数器

    // 生成唯一的 zxid
    public synchronized long generateZxid() {
        counter++;
        return (epoch << 32) | counter;
    }
}

说明:

  • epoch:领导周期,当新的 Leader 被选出时增加。
  • counter:自增计数器,每次写请求递增。

3.2 Proposal 广播

Leader 将事务转化为 Proposal 并广播给 Follower。

public class Leader {
    public void proposeTransaction(String data) {
        long zxid = generateZxid();
        Proposal proposal = new Proposal(zxid, data);
        
        // 广播 Proposal
        for (Follower follower : followers) {
            follower.receiveProposal(proposal);
        }
    }
}

public class Proposal {
    private long zxid;
    private String data;

    public Proposal(long zxid, String data) {
        this.zxid = zxid;
        this.data = data;
    }
}

说明:

  • Leader 将请求封装成 Proposal 并携带 zxid。
  • Proposal 广播给所有 Follower。

3.3 Follower 追加日志

Follower 接收到 Proposal 后,将其追加到本地日志。

public class Follower {
    private List<Proposal> log = new ArrayList<>();

    public void receiveProposal(Proposal proposal) {
        log.add(proposal); // 追加到本地日志
        sendAck(proposal.getZxid());
    }

    public void sendAck(long zxid) {
        System.out.println("ACK for zxid: " + zxid);
    }
}

说明:

  • Follower 将 Proposal 追加到本地日志中。
  • 发送 ACK 回 Leader。

3.4 Leader 提交 Proposal

Leader 收到过半 Follower 的 ACK 后,发送 COMMIT 指令。

public class Leader {
    public void commitProposal(long zxid) {
        for (Follower follower : followers) {
            follower.commit(zxid);
        }
    }
}

Follower 提交事务:

public class Follower {
    public void commit(long zxid) {
        System.out.println("Committed transaction with zxid: " + zxid);
    }
}

说明:

  • Leader 等待大多数 Follower 发送 ACK。
  • Leader 发送 COMMIT 指令。
  • Follower 提交事务。

四、关键实现细节与总结

4.1 操作顺序性核心保障

  1. 唯一有序 zxid:确保每个事务有唯一的顺序标识。
  2. 日志追加:Follower 严格按照 zxid 追加日志。
  3. 两阶段提交:只有过半节点确认后,事务才会被提交。

4.2 对比 Multi-Paxos

  • Multi-Paxos:共识,但不保证顺序性。
  • ZAB:通过 zxid 和广播日志,严格保证操作顺序。

五、总结

ZAB 协议通过 全局有序的 zxid 和 两阶段提交 机制,实现了分布式系统中事务的全局有序性。这种设计确保了 Zookeeper 能够在复杂的分布式环境中,提供一致性和高可用性。


责任编辑:武晓燕 来源: 架构师秋天
相关推荐

2020-10-09 14:13:04

Zookeeper Z

2022-03-23 18:58:11

ZookeeperZAB 协议

2023-11-03 08:13:35

ZAB协议负载均衡

2023-11-27 17:29:43

Kafka全局顺序性

2024-06-27 08:00:17

2010-12-15 10:13:22

2023-12-15 13:08:00

RocketMQ中间件消费顺序

2021-04-06 06:07:37

ZAB 协议原子广播协议网络协议

2023-12-04 09:23:49

分布式消息

2019-03-25 07:39:35

ID串行化消息顺序性高可用

2020-01-16 14:43:15

Paxos算法分布式

2010-09-07 14:47:42

2010-07-30 16:28:06

2019-04-08 15:11:12

HTTP协议Web

2010-07-09 12:18:37

Internet协议

2021-04-14 11:21:17

DeFi金融数据

2021-09-07 10:33:42

MySQL事务隔离性

2019-01-10 09:11:51

消息顺序性分布式服务端

2021-06-03 14:00:35

PolarDB

2020-05-19 13:34:20

ZookeeperZAB协议
点赞
收藏

51CTO技术栈公众号