kafka-reassign-partitions.sh 是 kafka 唯一支持在线副本重分配的官方工具,用于扩容、缩容、负载均衡等场景,需确保目标 broker 在线且磁盘充足,否则会卡在 pending_replication_factor 或 futurereplica 状态。

直接说结论:reassign-partitions.sh 不是“一键迁移”,它只提交任务;真正执行依赖 Controller 触发副本同步和 ISR 更新,且过程中必须确保目标 Broker 在线、磁盘充足、网络通畅——否则会卡在 pending_replication_factor 或长期停留在 FutureReplica 状态。
什么时候必须用 kafka-reassign-partitions.sh 而不是手动停机换 Broker?
当你需要在不中断服务的前提下调整副本分布时——比如扩容后把部分分区副本迁到新 Broker 上,或下线旧节点前把它的副本全部移走。手动停机换 Broker 会导致分区不可用(LeaderNotAvailable),而 kafka-reassign-partitions.sh 是 Kafka 唯一支持在线重分配副本的官方工具。
- 场景包括:Broker 扩容/缩容、磁盘负载不均、机架感知策略变更
- 不能用于跨集群迁移,也不能改变分区数量(
num.partitions) - 如果目标 Broker 的
log.dirs磁盘已满或权限不足,重分配会静默失败(日志里只有Failed to fetch replicas)
--reassignment-json-file 的结构必须严格匹配当前元数据
生成的 JSON 文件不是随便写的配置,它必须包含每个要调整的分区当前的 replicas 和目标 replicas,且 replica ID 必须是集群中真实存在的 Broker ID(查 kafka-broker-api-versions.sh --bootstrap-server 或看 zookeeper-shell.sh 下 /brokers/ids)。
- 错误示例:
"replicas": [1,2,5]中5是个已下线的 Broker → 后续所有副本同步卡住 - 顺序很重要:第一个 replica 默认为 leader,重分配后 leader 可能切换,但
replicas列表顺序影响优先级(如controlled shutdown时选谁当新 leader) - 建议用
--generate模式先生成模板,再人工校验修改,别手写
为什么执行后分区长时间显示 UnderReplicatedPartitions?
这通常不是失败,而是同步尚未完成。Kafka Controller 会逐个分区触发 addReplicaToIsr,但速度受 replica.fetch.wait.max.ms、网络延迟、副本大小影响。一个 10GB 的分区可能同步数分钟。
- 检查进度:用
kafka-topics.sh --describe --under-replicated-partitions看哪些还在 under-replicated - 关键指标:观察
KafkaController/ActiveControllerCount=1(确保只有一个 controller)、ReplicaManager/IsrShrinkRate是否持续上涨(说明 ISR 正在收缩) - 常见卡点:
log.cleaner.enable=false导致大日志段无法快速清理;replica.lag.time.max.ms设得太小(默认 10s),让新副本刚追上就被踢出 ISR
重分配中途失败后如何安全回滚?
没有自动回滚机制。一旦 --execute 提交,就只能等它完成或手动干预。如果发现目标 Broker 宕机或磁盘爆满,立刻做两件事:
- 停掉重分配进程(kill 对应的 shell 脚本进程,它本身不持久化状态)
- 用
kafka-topics.sh --describe确认哪些分区的replicas已更新但isr不全 → 这些分区处于危险状态 - 若新副本完全没同步,可尝试用
zookeeper-shell.sh手动删掉/admin/reassign_partitions节点(需谨慎,ZK 版本 ≥ 3.5.7 才支持 deleteall)
最稳妥的做法其实是提前在测试环境跑通全流程,因为线上重分配一旦开始,就进入了 Kafka 内部状态机,外部干预窗口很窄。










