Kafka + ZooKeeper架构基础介绍
一、整体架构
ZooKeeper 是 Kafka 2.8 之前 的必选协调组件,只做集群管控,不参与消息读写:
- 存储集群元数据(Broker、Topic、分区、副本、ISR 信息)
- 提供分布式锁与临时节点,实现 Kafka Controller 选举
- 感知 Broker 上下线
- 持久化分区 Leader 状态
Kafka 只负责:消息接收、存储、复制、消费。
二、ZooKeeper 在 Kafka 中的核心作用
1. 存储的关键元数据(ZK 节点路径)
| ZK 节点路径 | 作用 |
|---|---|
/brokers/ids/[brokerId] |
Broker 注册临时节点,标记存活 |
/brokers/topics/[topic] |
主题的分区数、副本分配方案 |
/brokers/topics/[topic]/partitions/[N]/state |
分区状态:Leader、ISR、副本集合 |
/controller |
保存当前 Controller 信息(临时节点) |
/config/topics/[topic] |
主题级配置 |
/admin/delete_topics |
待删除主题队列 |
2. 四大核心职责
-
Broker 注册与健康检测
- Broker 启动 → 创建临时节点
/brokers/ids/xx - 断开连接 → 节点自动删除 → Kafka 感知下线。
- Broker 启动 → 创建临时节点
-
Kafka Controller 选举
- 所有 Broker 争抢创建
/controller临时节点,成功即为 Controller。
- 所有 Broker 争抢创建
-
分区 Leader 状态持久化
- 每次 Leader 变更,结果写入 ZooKeeper,保证全局一致。
-
集群统一视图
- 所有 Broker 共享同一份元数据,不会出现脑裂。
三、ZooKeeper 配置(供 Kafka 使用)
zoo.cfg 完整配置
ini
# 基础时间单位 ms
tickTime=2000
initLimit=10
syncLimit=5
# 数据目录(生产必须独立磁盘)
dataDir=/data/zookeeper/data
dataLogDir=/data/zookeeper/log
clientPort=2181
# Kafka 集群需要高连接数
maxClientCnxns=2000
# 自动清理快照与日志
autopurge.snapRetainCount=5
autopurge.purgeInterval=24
# ZK 集群(3 节点示例)
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888
关键配置说明
dataDir:ZK 内存数据快照目录dataLogDir:事务日志目录(必须独立磁盘,性能关键)maxClientCnxns:Kafka 集群需调高,避免连接被拒autopurge:防止日志占满磁盘
节点标识(必须配置)
bash
echo "1" > /data/zookeeper/data/myid
myid 必须与 server.1/2/3 中的数字一致。
四、Kafka 连接 ZooKeeper 核心配置
server.properties 关键配置
ini
# 唯一标识
broker.id=1
# 监听地址
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://192.168.1.101:9092
# 日志存储
log.dirs=/data/kafka/logs
num.partitions=8
default.replication.factor=3
min.insync.replicas=2
# ======================
# ZK 核心配置
# ======================
zookeeper.connect=zk1:2181,zk2:2181,zk3:2181/kafka
zookeeper.connection.timeout.ms=10000
zookeeper.session.timeout.ms=18000
# 生产关闭自动创建主题
auto.create.topics.enable=false
delete.topic.enable=true
重点说明
zookeeper.connect末尾/kafka是命名空间,用于多集群隔离zookeeper.session.timeout.ms:超时即认为 Broker 已下线min.insync.replicas:最小同步副本数,保证数据不丢失
五、Kafka 分区主从机制:Leader / Follower / ISR
1. 主从角色
- Leader :每个分区只有一个,负责读写
- Follower :只从 Leader 同步数据,不提供读写
- ISR(In-Sync Replicas):与 Leader 保持同步的副本集合
2. 核心规则
- 生产者、消费者只与 Leader 交互
- Follower 异步拉取消息
- 只有 ISR 内的副本才有资格被选为新 Leader
3. 高可用保证
- Leader 宕机 → 从 ISR 中选新 Leader
- 配置
acks=all+min.insync.replicas=2可保证消息不丢失
六、Kafka Controller 选举流程(基于 ZK)
1. Controller 是什么?
集群中唯一的管理节点,负责:
- 分区 Leader 选举
- 副本分配与重分配
- 感知 Broker 上下线
- 同步元数据给所有 Broker
2. 选举流程(完全依赖 ZooKeeper)
sequenceDiagram
participant B1 as Broker 1
participant B2 as Broker 2
participant B3 as Broker 3
participant ZK as ZooKeeper
Note over B1,B3: 所有 Broker 启动
B1->>ZK: create /controller (ephemeral)
ZK-->>B1: 成功 → B1 成为 Controller
B2->>ZK: create /controller → 失败
B2->>ZK: watch /controller
B3->>ZK: create /controller → 失败
B3->>ZK: watch /controller
Note over B1,ZK: B1 宕机(网络断开)
ZK->>ZK: Session 超时(~6s)
ZK->>ZK: 删除 /controller 节点
ZK->>B2: Watch 触发
B2->>ZK: create /controller → 成功 → B2 成为新 Controller
特点:抢占式、简单、强依赖 ZK 临时节点特性。
七、Kafka 分区 Leader 选举流程
触发时机
- Broker 宕机
- 分区重分配
- 集群启动/停止
完整流程
graph TD
A[Controller 监听到 Broker 下线] --> B{获取该 Broker 上
所有 Leader 分区} B --> C{遍历每个分区} C --> D{查询该分区的 ISR 列表} D --> E{选择第一个存活的副本
作为新 Leader} E --> F{更新 ZK 中的
分区状态} F --> G{广播新 Leader
到所有 Broker} G --> H{客户端开始访问新 Leader}
所有 Leader 分区} B --> C{遍历每个分区} C --> D{查询该分区的 ISR 列表} D --> E{选择第一个存活的副本
作为新 Leader} E --> F{更新 ZK 中的
分区状态} F --> G{广播新 Leader
到所有 Broker} G --> H{客户端开始访问新 Leader}
详细步骤
- Controller 通过 ZK 监听到 Broker 下线
- 找到该 Broker 上所有 Leader 分区
- 对每个分区执行:
- 读取该分区的 ISR 列表
- 选择 第一个存活的副本 作为新 Leader
- 将新状态写入 ZK:
/brokers/topics/[topic]/partitions/[x]/state - Controller 把新元数据广播给所有 Broker
- 客户端开始访问新 Leader
八、Kafka 主从同步机制
- Follower 主动向 Leader 发起同步请求
- Leader 将消息写入后,同步给 Follower
- Follower 写入成功后回复 ACK
- 满足同步条件后加入 ISR
- 生产者
acks=all时:- 必须等 ISR 中所有副本 确认
- 才返回生产成功
九、常用运维命令(ZK + Kafka)
1. 查看当前 Controller
bash
bin/zookeeper-shell.sh zk1:2181 get /controller
2. 查看主题详情(Leader / ISR)
bash
bin/kafka-topics.sh --describe --topic test --bootstrap-server kafka1:9092
3. 查看在线 Broker
bash
bin/zookeeper-shell.sh zk1:2181 ls /brokers/ids
4. 查看分区状态
bash
bin/zookeeper-shell.sh zk1:2181 get /brokers/topics/test/partitions/0/state
十、关键故障机制
1. Broker 宕机
- ZK 会话超时 →
/brokers/ids/xx消失 - Controller 监听到 → 开始分区 Leader 迁移
2. Controller 宕机
/controller临时节点消失- 所有 Broker 重新选举 Controller
- 新 Controller 从 ZK 加载全量元数据
3. ZK 不可用影响
- 已有的消息读写正常
- 无法创建/删除 Topic
- 无法重新选举 Controller、分区 Leader
- 无法上下线 Broker
十一、总结
- ZooKeeper:Kafka 集群的"配置中心 + 协调中心"。
- Broker 注册:依靠 ZK 临时节点实现存活检测。
- Controller 选举 :争抢 ZK
/controller临时节点实现。 - 分区主从:Leader 提供读写,Follower 同步,ISR 保证高可用。
- Leader 选举:由 Controller 从 ISR 中选出,结果存入 ZK。
- ZK 作用边界:只管集群协调,不管消息收发。