Skip to content

Kafka 中 Zookeeper 的作用? ​

  • 标签:Kafka、消息队列、后端

🏛 业务架构师 ​

Kafka(2.8 之前)把 Zookeeper 用在三处,每一处都影响业务侧的确定性:

  • 元数据存储:broker 注册、topic/分区配置、leader 副本信息都存 ZK。控制面数据与数据面分离;
  • Controller 选举:第一个注册 /controller 临时节点的 broker 成为 Controller,负责分区 leader 选举与故障转移。Controller 更替期间可能触发大规模分区选举,业务表现为消费延迟飙升;
  • 消费者偏移(旧版本):0.8/0.9 时代 offset 孤儿般放在 ZK,ZK 写压力一大 consumer 就抖动,后来迁到 __consumer_offsets 主题,自管理——这段历史本身就说明"把业务高频状态放外部协调系统"是错配。

业务视角我总结两点:

  1. 外部依赖的隐性成本:ZK 抖动 → Controller 切换 → 分区重选 → 消费延迟,故障会沿着依赖链传导放大。容量规划和故障演练必须把依赖链画全,不能只看 Kafka 本身;
  2. 演进印证了"按需协调":KRaft 用自日志复制替代 ZK,本质是承认 Kafka 需要的共识强度和数据规模,ZK 模型已经不匹配。

这也是我评审架构的通用问题:每个外部组件在链路里承担什么、它抖了业务抖多狠、有没有降级路径。答不上来的依赖,就是下一次线上事故的候选名单。

🏗 系统架构师 ​

ZooKeeper 在老版本 Kafka(2.8 前)里承担所有元数据与协调职责:

  • 元数据存储:broker 注册(/brokers/id)、topic 与分区副本分配信息、ISR 列表(controller 写回);
  • Controller 选举:所有 broker 向 ZK 抢注 /controller 临时节点,抢到的成为 controller,负责分区 leader 选举与故障转移;
  • 消费者协调(老版本):0.9 前消费组通过 ZK 管理成员与 offset(0.9 后迁到内部 topic __consumer_offsets,这一步已经是在给 ZK 减负);
  • 配置与配额存储。

痛点与演进:watch 风暴 + 全量元数据推送让 controller failover 达到分钟级,规模一大就成为瓶颈,所以才有 KRaft 把这些职责整体内移——元数据日志化存内部 topic、Raft 选 controller,不再依赖外部协调系统。

从架构视角看:ZK 承担的是"注册中心 + 配置中心 + 选主服务"三合一,小规模下非常省事,但元数据规模与变更频率上去后,任何外部协调组件都会成为扩展边界,这是我评估"要不要引入协调服务"时的核心判断依据。

💻 全栈开发专家 ​

ZooKeeper 时期承担了四块职责:

  1. Broker 注册与存活检测:broker 启动注册临时节点 /brokers/ids/xx,断开时节点消失,Controller 感知宕机。
  2. Controller 选举:所有 broker 抢注 /controller 临时节点,抢到的成为 Controller,负责分区 leader 选举和故障转移。
  3. 元数据存储:topic、partition、ISR 副本列表、配置都存在 znode 里,客户端/Controller 通过 watch 感知变化。
  4. 消费者协调(旧版):0.8 时代 consumer offset 和 rebalance 都靠 ZK,0.9 起挪到内部 topic __consumer_offsets,由 GroupCoordinator 管理——这是"ZK 被架空"的第一步。

为什么要移除(引出 KRaft):分区规模上去后元数据全量写 znode、watch 风暴导致 Controller 故障恢复慢;两套系统运维成本高;ZK watch 与 Kafka 状态机有不一致窗口。KRaft 用 Raft 日志自管理元数据,Controller 切换从分钟级降到秒级。

面试话术:先讲四个职责,再点一句"这些职责 0.9 之后逐步内化,最终 KRaft 完全替代",体现的是对演进脉络的理解。