← [ BACK_TO_NOTES ]

Apache ZooKeeper

ZooKeeper 的分布式协调主笔记:从 znode、session、ephemeral/sequential node、watch、quorum 到服务发现、选主、分布式锁与和 etcd/Kafka 的边界。

#concept #growing #backend #architecture

[!info] related notes

Apache ZooKeeper

[!abstract] 一句话定位 ZooKeeper 是分布式协调服务,以层级 ZNode、Session、Ephemeral / Sequential Node、Watch 和 Quorum 为核心,常用于成员关系、配置、选主和锁。它存的是小规模协调状态,不是通用业务数据库或消息日志。

核心命名空间

/
├─ services/api/instance-0001
├─ config/payment
└─ election/worker-0000000003

ZNode 包含少量 Data、Version、Children 和 ACL。数据读取和写入以单个 ZNode 为原子边界。

Persistent、Ephemeral 与 Sequential

Persistent ZNode

除非显式删除,否则长期存在,适合稳定配置和命名空间结构。

Ephemeral ZNode

与创建它的 Session 生命周期绑定:

Session alive   → Ephemeral ZNode exists
Session expires → ZNode removed

适合服务注册、成员关系和临时 Ownership。Ephemeral Node 不能拥有 Children。

Sequential ZNode

创建时自动附加递增序号:

/election/node-0000000001
/election/node-0000000002

适合 Leader Election、Lock Queue 和有序 Ownership。

Session 不是 TCP Connection

客户端可以在 Session Timeout 内重连其他 ZooKeeper Server 并继续同一 Session。真正 Session Expiration 后:

  • Ephemeral ZNode 被删除;
  • Watch / Ownership 语义改变;
  • 旧 Client 必须停止把自己当有效 Owner。

网络短暂断开时,Client 不能确定自己的状态是否仍然最新,应进入保守模式。

Watch

经典 Watch 是一次性触发:

read + register watch
→ znode changes
→ receive event
→ watch consumed
→ re-read and register again

ZooKeeper 3.6+ 也支持 Persistent / Recursive Watch,但 Watch 仍更适合“状态变了,请重新读取并 Reconcile”,不是持久消息日志。

[!warning] Watch 不能保证看到每个中间状态 断线、重注册窗口和连续多次变化都可能让 Client 只观察到最终状态。业务正确性应建立在读取当前状态和 Version 上,而不是把每个 Watch Event 当不可丢事件。

一致性保证

ZooKeeper 的写操作可线性化排序;普通读可以由连接的 Server 本地响应,因此可能读到相对最新 Quorum 状态较旧的数据。

核心保证包括:

  • 客户端操作顺序得到保持;
  • 更新原子成功或失败;
  • 同一 Session 切换 Server 不会倒退到更旧视图;
  • 成功确认的更新不会在故障恢复后被回滚。
Write → globally ordered
Read  → fast, but may be stale

因此不能简单说“ZooKeeper 所有读写都是强一致”。

Ensemble、Leader 与 Quorum

ZooKeeper 集群由 Ensemble 组成。写入经 Leader 排序并由多数派确认:

Client Write
→ Leader proposal
→ Followers acknowledge
→ quorum commit
→ apply

常见使用 3 或 5 个 Voting Members。增加成员会提高可容忍故障数,也增加写协调成本。

三个典型 Recipe

服务发现

service instance
→ create ephemeral /services/api/<id>

client
→ list children + watch
→ maintain endpoint set

Leader Election

candidates create ephemeral sequential nodes
→ smallest sequence becomes leader
→ each follower watches predecessor

只 Watch 前驱可减少所有候选者同时被唤醒的 Herd Effect。

Distributed Lock

同样可用 Ephemeral Sequential Node 形成等待队列。但保护外部数据库、文件或设备时,仍需要 Version / Fencing Token,防止 Session 已失效的旧 Owner 继续执行。

ZooKeeper 与 etcd

ZooKeeper
→ hierarchical namespace
→ Session / Ephemeral / Sequential ZNode
→ Watch recipes

etcd
→ flat ordered KV ranges
→ global Revision
→ Lease / Watch / Txn / CAS
→ Raft API model

现代云原生系统常使用 etcd;传统 Java、大数据和旧基础设施生态中仍广泛存在 ZooKeeper。

Kafka 的现代版本边界

Kafka 过去长期依赖 ZooKeeper 管理元数据。Kafka 4.x 已移除 ZooKeeper 模式,只支持 KRaft。

因此:

  • 学 ZooKeeper 仍有分布式协调价值;
  • 学现代 Kafka 时不要再把 ZooKeeper 当默认组件;
  • 维护 Kafka 3.x 旧集群时才需要理解迁移历史。

适用与不适用

适合:配置协调、成员关系、服务发现、Leader Election、Distributed Lock Recipe、小规模关键元数据。

不适合:大量业务数据、高吞吐 Event Log、Cache、大文件、复杂查询和分析。

高频故障

Session Expiration

Client Pause、网络问题或处理 Watch 太慢都可能导致 Session 失效。恢复时必须重建 Ephemeral State,而不是继续使用旧 Ownership。

Herd Effect

大量 Client Watch 同一 ZNode,变化时同时唤醒。使用分层状态、前驱 Watch、缓存和 Reconciliation 降低冲击。

大 ZNode / 大 Children Set

ZooKeeper 为协调而设计。大 Value、巨量 Children 或高频写会增加内存、网络和 Watch 成本。

磁盘与 Swap

事务日志磁盘延迟和 Swap 会直接影响写入及时性与 Session 稳定,应避免与高 I/O 工作负载争用。

观测重点

leader / follower state
outstanding requests
watch count
latency min/avg/max
znode count / data size
session count / expiry
packet rate
transaction log / snapshot / disk latency
quorum health

面试掌握标准

  • ZNode、Persistent、Ephemeral、Sequential;
  • Session 与 TCP Connection 的区别;
  • Watch 的一次性/持久模式和漏中间状态边界;
  • 写线性化、读可能 stale;
  • Quorum 与 Leader;
  • Election / Lock Recipe;
  • ZooKeeper 与 etcd 的差异;
  • Kafka 4.x 不再依赖 ZooKeeper。

官方资料

创建于 2026/9/4 更新于 2026/9/4
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本