复制、扩容与故障恢复
每个分区只有一个 Leader 接收客户端读写,Follower 从 Leader 同步数据。ISR 是与 Leader 保持同步的副本集合;当 Producer 使用 acks=all 且 Topic 的 min.insync.replicas=2 时,ISR 少于 2 个会拒绝写入,这是用可用性保护已确认数据的设计。

1. 检查 Leader 与 ISR
# 查看分区 Leader、全部副本和 ISR;Replica 与 ISR 不一致需要立即关注。
/opt/kafka/bin/kafka-topics.sh --describe \
--bootstrap-server kafka-1.example.internal:9092 --topic orders.created.v1
# 仅输出副本不足分区;生产巡检中无输出才是预期状态。
/opt/kafka/bin/kafka-topics.sh --describe --under-replicated-partitions \
--bootstrap-server kafka-1.example.internal:9092
# 仅输出没有可用 Leader 的分区;有输出通常意味着该分区不可读写。
/opt/kafka/bin/kafka-topics.sh --describe --unavailable-partitions \
--bootstrap-server kafka-1.example.internal:9092
不要为了快速恢复开启 unclean.leader.election.enable=true。它可能从落后副本选出 Leader,从而丢弃未同步的已确认消息;只有明确接受数据损失并经应急审批后才能考虑。
2. Broker 维护与重分配
维护 Broker 前先确认没有副本不足分区,再分批迁移副本或受控停机。副本重分配会消耗网络与磁盘 I/O,应分 Topic 执行并持续观察 ISR、生产延迟和 Consumer Lag。
{
"version": 1,
"partitions": [
{
"topic": "orders.created.v1",
"partition": 0,
"replicas": [1, 2, 4],
"log_dirs": ["any", "any", "any"]
}
]
}
# 根据真实 Topic 清单生成候选方案;先审核输出,不能直接执行未知分配。
/opt/kafka/bin/kafka-reassign-partitions.sh --generate \
--bootstrap-server kafka-1.example.internal:9092 \
--topics-to-move-json-file topics.json --broker-list "1,2,3,4"
# 将审核后的方案写入 reassignment.json 后提交任务。
/opt/kafka/bin/kafka-reassign-partitions.sh --execute \
--bootstrap-server kafka-1.example.internal:9092 \
--reassignment-json-file reassignment.json
# 反复验证直到完成;完成前不可下线源或目标 Broker。
/opt/kafka/bin/kafka-reassign-partitions.sh --verify \
--bootstrap-server kafka-1.example.internal:9092 \
--reassignment-json-file reassignment.json
3. ZooKeeper 故障边界
ZooKeeper 失去法定人数时,已建立的数据流可能短时继续,但 Controller 选举、元数据变更和分区故障转移会受阻。恢复顺序是先恢复 ZooKeeper 法定人数和数据一致性,再处理 Broker;绝不能删除 ZooKeeper 数据目录来“重建”仍有关联 Broker 的生产集群。
| 故障 | 首要动作 |
|---|---|
| 单 Broker 不可用 | 检查 Leader、ISR、磁盘和网络,恢复后等待副本追平 |
| 多副本脱离 ISR | 停止高风险变更,检查复制流量、磁盘 I/O 和 Broker 延迟 |
| ZooKeeper 单节点故障 | 保持其余节点运行,核对 myid 与持久卷后恢复节点 |
| ZooKeeper 无法形成法定人数 | 按备份和变更记录恢复足够节点,避免多个孤立节点独立启动 |