必须手写或脚本生成符合Kafka要求的reassignment.json,含version(固定为1)和partitions数组,每个元素指定topic、partition及整数型replicas数组;常见错误是replicas写成字符串或遗漏分区,导致InvalidPartitionsException或静默跳过。

怎么生成 reassignment JSON 文件
必须手写或用脚本生成符合 Kafka 要求的 reassignment.json,结构不能错。它包含两个顶层字段:version(固定为 1)和 partitions(数组),每个元素指定 topic、partition 和 replicas(副本所在 broker ID 列表)。
常见错误是把 replicas 写成字符串或漏掉某个分区——Kafka 会直接报 InvalidPartitionsException 或静默跳过。
-
replicas必须是整数数组,比如[101, 102, 103],不能是["101","102"] - 只挪部分分区?没问题,但 JSON 里只列要挪的,别把没动的也塞进去
- 新节点 broker ID 必须已在集群中注册且存活,否则执行时卡在
Waiting for admin client to be ready
怎么用 --generate 模式预生成方案
如果只是想把某些 topic 的分区均匀摊到新加入的 broker 上,别手写 JSON,用 kafka-reassign-partitions.sh --generate 更安全。
它会读取当前分配、结合你给的 --broker-list(比如 "101,102,103,104"),自动计算出最小迁移量的方案,并输出两段 JSON:一段是建议的 reassignment,一段是当前状态(用于回滚)。
- 必须加
--topics-to-move-json-file,内容是{"topics": [{"topic": "my-topic"}], "version": 1} - 输出的“建议 JSON”要重定向保存,别直接复制终端里带换行缩进的版本——JSON 解析器对空白敏感
- 生成后先用
kafka-topics.sh --describe确认源分区 leader 分布,避免新方案把所有 leader 都压到一个 broker 上
执行 reassignment 时为什么卡住或失败
执行 --execute 后长时间无响应,大概率是副本同步没完成,而不是工具挂了。Kafka 会等 ISR(in-sync replicas)全部追上才标记完成。
典型现象:命令返回 Successfully started reassignment,但 --verify 一直显示 reassignment in progress,甚至几小时不动。
- 检查新节点磁盘是否满、网络是否丢包(
tcpdump -i any port 9092看有没有大量重传) - 调大
replica.fetch.wait.max.ms(默认 500ms)和replica.fetch.response.max.bytes(默认 10MB),尤其当消息体大时 - 别在高峰期执行;如果卡太久,可用
--cancel中断,但已复制的数据不会回退,下次再跑要清理目标 broker 的 log.dirs 下对应分区目录
verify 阶段看到 “Failed” 怎么办
--verify 报 Failed 不一定等于迁移失败,可能是状态未刷新及时。先等 30 秒再重试;仍失败,就查 kafka-topics.sh --describe --topic X 输出里的 Replicas 和 Isr 字段。
真正的问题往往藏在这几个地方:
-
Isr少于Replicas数——说明至少一个副本没同步上,看那个 broker 的server.log里有没有Failed to fetch或Connection refused - 目标 broker 的
log.dirs权限不对,导致无法创建分区子目录(常见于用 root 启动 Kafka 但 data 目录属主是 kafka 用户) - 旧 broker 已下线但还在
replicas列表里——verify 会持续报错,必须手动编辑 JSON 重新 execute
迁移不是原子操作,ISR 收敛前任何 broker 故障都可能导致数据不可用,线上操作务必盯紧监控里的 UnderReplicatedPartitions 指标。











