KafkaNotes

第 22 章:集群运维:扩容、再分配、迁移与升级

zjc 于 2026-01-22 发布

这是《Kafka 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 集群不是搭完就完事。本章覆盖日常最重的几类运维操作:扩容与数据均衡、跨集群迁移、滚动升级、备份与容灾。

22.1 扩容 Broker

步骤

1. 准备新节点:装同版本、配置 log.dirs/监听器/安全
2. 分配 node.id 并注册(KRaft combined 模式需评估 controller 容量)
3. 启动并确认注册成功
4. 观察元数据同步、无告警

验证:

bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 \
  | grep -E '^newbroker'
bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --replication

注意:新 Broker 上线后不会自动获得任何数据。 Kafka 不会自动迁移分区,必须执行分区再分配。

22.2 分区再分配

生成分配方案

cat > topics-to-move.json <<'EOF'
{
  "topics": [
    {"topic": "order-events"}
  ],
  "version": 1
}
EOF

bin/kafka-reassign-partitions.sh \
  --bootstrap-server localhost:9092 \
  --topics-to-move-json topics-to-move.json \
  --broker-list 1,2,3,4 \
  --generate

输出两部分:当前分配(Current partition assignment)与建议方案(Proposed partition assignment)。审查建议方案(副本是否跨机架、是否过于集中)后保存为 reassignment.json

执行

bin/kafka-reassign-partitions.sh \
  --bootstrap-server localhost:9092 \
  --reassignment-json-file reassignment.json \
  --execute

# 查看进度
bin/kafka-reassign-partitions.sh \
  --bootstrap-server localhost:9092 \
  --reassignment-json-file reassignment.json \
  --verify

运维要点

22.3 Leader 均衡

再分配只改副本位置,Leader 可能仍集中在老节点:

# 查看分布
bin/kafka-leader-election.sh --bootstrap-server localhost:9092 \
  --election-type preferred --all-topic-partitions

配合 Broker 配置:

auto.leader.rebalance.enable=true
leader.imbalance.per.broker.percentage=10
leader.imbalance.check.interval.seconds=300

规模化运维通常引入 Cruise Control:它基于负载模型(CPU、磁盘、网络、副本数)自动生成均衡方案,支持增量目标(balance goals)与异常检测,是大型集群的标配。

22.4 跨集群迁移:MirrorMaker 2

MM2 基于 Kafka Connect 实现 topic 复制,支持:

最小配置 mm2.properties

clusters = src, dst
src.bootstrap.servers = src-broker1:9092
dst.bootstrap.servers = dst-broker1:9092

src->dst.enabled = true
src->dst.topics = .*
dst->src.enabled = false

replication.factor = 3
checkpoints.topic.replication.factor = 3
heartbeats.topic.replication.factor = 3

# 新集群的 topic 会加前缀 src.(DefaultReplicationPolicy)
# topics = order-events -> src.order-events

启动:

bin/connect-mirror-maker.sh mm2.properties

切流流程

1. 开启 MM2,让 dst 持续追 src
2. 校验数据一致性(抽样 offset/内容比对)
3. 生产端灰度切到 dst(或切 DNS/负载入口)
4. 消费组按 checkpoint 同步位移
5. 观察稳定后停写 src,保留回滚窗口

注意 DefaultReplicationPolicy 会给目标 topic 加 src. 前缀;若想保留原名,用 IdentityReplicationPolicy,但要非常小心双活场景的循环复制。

22.5 滚动升级

标准流程:

1. 阅读目标版本 release notes 与升级路径(是否支持跨版本)
2. 备份配置与元数据
3. 在测试集群演练
4. 按批次(如每批 1 台或 10%)升级:
     a. 下线前确认该 Broker 上的分区有其他 ISR
     b. 停进程、替换二进制、改配置
     c. 启动、观察入组/ISR 恢复/无告警
     d. 进入下一批
5. 全部完成后跑功能与性能回归

关键观察点:UnderReplicatedPartitions 回到 0、Controller 仲裁正常、客户端错误率无异常、请求延迟恢复基线。

22.6 备份与容灾

两层含义

手段 恢复目标
集群内 多副本(RF=3、跨机架) 节点故障
集群间 MM2 异地复制、云厂商跨 AZ 机房/区域故障
误操作 定期导出/对象存储归档、版本化配置 误删 topic、错误配置

同城双活与异地灾备

同城双活:
  两个机房各部署集群,MM2 双向复制
  按业务分片写入,避免同 key 双写冲突

异地灾备:
  主集群单向复制到备集群
  RPO = 复制延迟,RTO = 切流时间
  定期演练切换,否则预案只是纸面安全

明确 RPO/RTO:复制延迟 10s、切流 5 分钟,和复制延迟 1 小时、切流半天,是完全不同的架构投入。

22.7 日常运维节奏

每日:
  巡检 lag / ISR / 磁盘 / 告警

每周:
  容量趋势 review、慢查询 topic 分析
  配置漂移对比

每月:
  故障演练(kill broker、切 Controller)
  僵尸 topic 清理、ACL 审计

每季度:
  灾备切换演练、大版本升级评估

把节奏写成 checklist,比“等出事再查”可靠得多。

本章小结

思考题

  1. 为什么 Kafka 不在新 Broker 上线时自动迁移分区?自动迁移有什么风险?
  2. MM2 用 IdentityReplicationPolicy 保留原名时,如何防止双活循环复制?
  3. 设计一个 RPO<30s、RTO<10min 的异地容灾方案,列出关键组件与演练计划。