本页目录

共识在实际系统中的实践

etcd、Consul、ZooKeeper——三个实际系统中同一个共识问题的三种工程解法。Raft+boltdb、Raft+Gossip、ZAB,共识协议是核心但不是全部:线性一致性读、租约、watch 机制和成员管理各有一套工程取舍。

etcd

etcd 是最广泛使用的 Raft 实现(Go),Kubernetes 的核心依赖——所有 K8s 对象(Pods, Services, ConfigMaps)都存在 etcd 中。

架构

etcd 架构:gRPC 请求经 Raft 共识写入 boltdb,MVCC 管理历史版本 Client gRPC etcd server Raft layer 共识 + log replication Storage boltdb(B-tree,持久化) MVCC 多版本 key-value(历史 revision) 写路径:client → Raft propose → commit → apply to boltdb → response;MVCC 让读可按版本回溯。

每个写请求 → Raft propose → commit → apply to boltdb → response。读请求有两种模式:

  • Serializable Read: 从本地 boltdb 直接读(不经过 Raft)→ 可能返回旧数据(stale)
  • Linearizable Read (默认): ReadIndex 机制——1) leader 记录当前 commitIndex; 2) 发心跳给多数 follower 确认自己仍是 leader; 3) 等状态机 apply 到 ≥ 该 commitIndex; 4) 读。这保证了读不会看到已被更替的 leader 的数据。

Watch

etcd 支持 long-poll watch: client 指定 key prefix → server 返回 change events。Kubernetes 的 controller pattern (Informer) 基于 etcd watch 实现。

Consul

Consul 用 Raft 做服务目录(service catalog)的一致性复制,用 Gossip (SWIM) 做成员发现和健康检查传播——分离了"需要一致性的数据"和"可以最终一致的数据"。

Consul:Raft 管强一致数据,Gossip 管最终一致数据 Consul Agent Raft Consul Server 3-5 个,Raft 复制 service catalog 强一致(谁在提供什么服务) Gossip 所有 Consul Agents 成员发现,健康状态传播 最终一致(谁还活着) 设计原则:服务注册需要强一致 → Raft;成员存活检测可用最终一致 → Gossip—— 分离"需要一致性的数据"和"可以最终一致的数据"。

设计原则:服务注册(谁在提供什么服务)需要强一致 → Raft。成员存活检测(谁还活着)可用最终一致 → Gossip。

ZooKeeper (ZAB 协议)

ZooKeeper 的 ZAB (ZooKeeper Atomic Broadcast) 协议比 Raft 早 8 年,设计目标不同:

  • Raft: 所有 server 的 log 完全相同
  • ZAB: leader 的 log 是权威的,followers 可能 leader 多一些 entries(但可以被 overwrite)

ZAB 的"顺序保证"不是全局 linearizability order 像 Raft,而是 FIFO client order——client 的多个请求保持发送顺序,但不同 client 之间没有顺序保证。

为什么 ZooKeeper 还活着

ZooKeeper 的先发优势和 Java 生态导致大量遗留系统依赖它(Kafka 旧版本、Hadoop、HBase),但新系统越来越倾向 etcd(更简、Go-native、K8s 依赖)。

共识的应用场景

共识不是万能的——它解决的是"多个节点对单个值达成一致":

该用共识:                   不该用共识:
  - Leader election          - 大容量数据复制 (用 gossip)
  - 分布式锁                 - 非 leader-based 的复制
  - 配置中心                 - 健康检查
  - 元数据管理               - 日志聚合

大多数系统不需要共识——它们需要的是最终一致性的复制(Gossip, async replication)或者单 master + WAL(大多数 SQL DB 的主从复制)。

参考

  • etcd: github.com/etcd-io/etcd, raft.github.io
  • Consul: consul.io/docs/architecture
  • ZooKeeper: "ZooKeeper: Wait-free coordination for Internet-scale systems" (2010)

Keywords: etcd, Raft, boltdb, Consul, Gossip, ZooKeeper, ZAB, linearizable read, ReadIndex