不能直接用 kafka-reassign-partitions.sh 迁移分区数据,因为它仅移动副本,不触发 Leader 选举、不校验同步进度、不更新消费者 offset 映射,易导致 UnderReplicatedPartitions、消费延迟或负载不均。

为什么不能直接用 kafka-reassign-partitions.sh 迁移分区数据?
因为 Kafka 的分区重分配(reassignment)本身不等于“数据重新平衡”——它只是把分区副本从旧 Broker 移到新 Broker,但不会自动触发 Leader 选举或消费者位点重映射。如果只跑一遍脚本,可能出现:部分分区卡在 UnderReplicatedPartitions 状态、消费者持续拉取旧 Leader 上的旧数据、新副本同步滞后甚至失败。
关键点在于:kafka-reassign-partitions.sh 只负责副本移动,不处理消费者组 offset 映射、不校验副本同步进度、也不保证迁移后分区 Leader 分布均匀。
执行前必须验证的三件事
跳过这步,90% 的迁移会卡在中间状态或引发消费延迟:
-
确认所有目标 Broker 的
log.dirs路径有足够磁盘空间,且磁盘 I/O 不饱和(iostat -x 1查看 %util > 80 就别动) -
检查 Topic 当前 ISR 列表是否完整:运行
kafka-topics.sh --bootstrap-server x.x.x.x:9092 --describe --topic my-topic,确保每个分区的 ISR 都包含全部副本,否则迁移中副本无法追上 Leader -
确认没有消费者组正在提交 offset 到
__consumer_offsets的旧分区:用kafka-consumer-groups.sh --bootstrap-server ... --group my-group --describe查看COORDINATOR所在 Broker 是否是待下线节点;如果是,先滚动重启该 Broker 上的消费者实例
分两步走:生成计划 + 滚动执行
不要一次性提交全量 reassignment JSON —— 容易触发集群级副本同步风暴。正确做法是按 Broker 维度拆解:
第一步,用 kafka-reassign-partitions.sh --generate 生成基础方案,然后手动编辑输出的 JSON,把要迁出的分区按目标 Broker 分组(例如每组最多 3 个分区),每组单独保存为 reassign-001.json、reassign-002.json …
第二步,逐个执行:
kafka-reassign-partitions.sh \ --bootstrap-server x.x.x.x:9092 \ --reassignment-json-file reassign-001.json \ --execute
每次执行后等 5–10 分钟,用 kafka-reassign-partitions.sh --verify 确认该批次完成(输出含 Successfully completed reassignment),再跑下一批。
注意:--verify 必须针对同一份 JSON 文件,不能用新生成的文件去 verify 旧任务。
迁移后必须做的两件事
很多人以为 --verify 成功就结束了,其实还有隐藏问题:
-
强制刷新消费者组元数据:哪怕消费者没重启,也要发一次
ConsumerGroupCommand的--reset-offsets(哪怕只是 --to-current),触发客户端重新 fetch 分区元数据,否则可能继续往已迁移走的旧 Leader 发 fetch 请求 -
检查
PreferredReplicaLeaderElection是否生效:迁移后 Leader 很可能还在旧 Broker 上。手动触发一次:kafka-leader-election.sh --bootstrap-server ... --election-type preferred --topic my-topic,否则负载不均问题照旧
最常被忽略的是后者:即使所有副本都迁完了,Leader 还卡在原 Broker,相当于白忙一场。


















