基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

如果单台Broker的磁盘即将打满,如何在不停机的情况下安全地将部分Partition迁移到其他Broker上?

知识点图片

在Kafka集群中,单台Broker磁盘即将打满是一个常见的生产紧急情况。Kafka原生支持在不停机、不影响客户端读写的情况下,通过副本迁移(Partition Reassignment)来平衡磁盘空间。

以下是安全、平滑地将部分Partition迁移到其他Broker的标准操作流程(SOP):

第一阶段:紧急缓解(可选,争取时间)

在做数据迁移前,如果磁盘已经到达95%以上,随时可能宕机,建议先执行以下操作争取时间:

  1. 临时缩短该Broker上大Topic的保留时间(Retention)
    bash
    kafka-configs.sh --bootstrap-server <broker-list> --entity-type topics --entity-name <heavy-topic> --alter --add-config retention.ms=86400000
    注:这会让Kafka立刻清理过期数据,释放空间。迁移完成后可改回原值。

第二阶段:精准定位与计划

不要盲目迁移整个Topic,只迁移占用空间最大的几个Partition。

1. 找出占用空间最大的Partition
登录磁盘告警的Broker,进入Kafka的 log.dirs 目录,找出最大的文件夹:

bash
du -sh * | sort -hr | head -n 10

假设找到占用最大的是 order-events-2(Topic为order-events,Partition 2),当前在 Broker 1(即将满的机器)上。

2. 确定目标 Broker
查看集群中其他Broker的磁盘空间,挑选1~2台空间充足的Broker(假设挑选了 Broker 2 和 Broker 3)。

第三阶段:手工编写迁移计划(最精准安全的方式)

使用Kafka自带的 kafka-reassign-partitions.sh 工具。为了精准控制,我们手动编写重分配的JSON文件,而不是让Kafka自动生成。

创建一个 reassign.json 文件:

json
{
  "version": 1,
  "partitions": [
    {
      "topic": "order-events",
      "partition": 2,
      "replicas": [2, 3], 
      "log_dirs": ["any", "any"]
    }
  ]
}
  • 解释:上述JSON告诉Kafka,将 order-eventspartition 2 的副本迁移到 Broker 2 和 Broker 3 上(从而将其从 Broker 1 上移走)。
  • 安全建议:一次不要迁移太多,建议每次只迁移 1~3 个大的Partition,分批进行。

第四阶段:执行限流迁移(保证不停机的关键)

如果不限流,底层大量复制数据会打满网卡和磁盘IO,导致Broker假死、Leader选举超时,从而引起停机。

1. 执行迁移并设置限流(Throttle)
使用 --throttle 参数限制复制速度(单位是 Bytes/sec)。例如限制为 50MB/s(50000000):

bash
kafka-reassign-partitions.sh --bootstrap-server <broker-list> \
--reassignment-json-file reassign.json \
--execute \
--throttle 50000000

执行后,Kafka会输出一段当前的副本分配状态(Current partition replica assignment),请务必将这段JSON保存下来,以便出现意外时可以回滚。

第五阶段:监控与验证

1. 查看迁移进度

bash
kafka-reassign-partitions.sh --bootstrap-server <broker-list> \
--reassignment-json-file reassign.json \
--verify

你会看到类似 is still in progress(正在进行)或 completed successfully(已完成)的提示。

2. 观察磁盘空间

  • 目标Broker的磁盘空间会逐渐增加。
  • 注意:源Broker(Broker 1)的磁盘空间不会立刻减少。Kafka的机制是:先在目标Broker创建新副本 -> 复制数据 -> 追上进度成为ISR -> 发生Leader切换 -> 最后才会删除旧Broker上的副本。当看到Broker 1磁盘空间突然下降时,说明该Partition迁移彻底完成了。

第六阶段:清理限流(极其重要!)

迁移完成后(--verify 显示全部成功),必须移除限流配置。如果不移除,未来该Topic正常的副本同步也会受到这个速度限制,非常危险。

重新运行一遍没有 --throttle--verify 命令,或者显式清理:

bash
kafka-configs.sh --bootstrap-server <broker-list> --entity-type brokers --entity-default --alter --delete-config leader.replication.throttled.rate,follower.replication.throttled.rate

kafka-configs.sh --bootstrap-server <broker-list> --entity-type topics --entity-name order-events --alter --delete-config leader.replication.throttled.replicas,follower.replication.throttled.replicas

💡 高级技巧与注意事项

  1. 单机多磁盘(JBOD)迁移方案
    如果你的单台Broker挂载了多块磁盘(log.dirs 配置了多个路径),并且只是其中一块磁盘满了。从 Kafka 1.1.0 开始,支持Broker内部磁盘间迁移
    只需在编写JSON时,利用 log_dirs 属性指定目标磁盘路径的绝对目录即可,无需跨网络传输,速度极快且不消耗网络带宽。

  2. 客户端完全无感吗?
    是的。Kafka在迁移完成的最后一刻,会自动进行Leader切换。客户端(Producer/Consumer)通过定期拉取Metadata感知到Leader变化,会自动重连到新的Broker上,会有毫秒级的延迟,但不会报错或停机。

  3. 避开高峰期
    尽管做了限流,依然建议在业务低谷期(如凌晨)进行此类运维操作,将风险降到最低。

00:00
00:00