第 15 章 使用分区重新分配工具
在扩展 Kafka 集群时,您可能需要添加或删除代理并更新分区的发布或主题的复制因素。要更新分区和主题,您可以使用 kafka-reassign-partitions.sh
工具。
您可以使用 kafka-reassign-partitions.sh
工具更改主题的复制因素。该工具还可用于重新分配分区并在代理间平衡分区分布以提高性能。但是,建议您使用 Cruise Control 进行自动分区重新分配和集群重新平衡,并更改主题复制因素。Cruise Control 可以在不停机的情况下将主题从一个代理移到另一个代理,这是重新分配分区的最高效方法。
15.1. 分区重新分配工具概述
分区重新分配工具提供以下功能来管理 Kafka 分区和代理:
- 重新分发分区副本
- 通过添加或删除代理来扩展集群,并将 Kafka 分区从大量载入的代理移到使用不足的代理中。要做到这一点,您必须创建一个分区重新分配计划,标识要移动哪些主题和分区,以及移动它们的位置。建议对这类操作进行 Cruise Control,因为它 可自动执行集群重新平衡过程。
- 扩展和缩减主题复制因素
- 增加或减少 Kafka 主题的复制因素。要做到这一点,您必须创建一个分区重新分配计划,标识分区之间的现有复制分配,并使用复制因素更改更新分配。
- 更改首选领导
- 更改 Kafka 分区的首选领导。如果当前首选领导不可用,或者要在集群中的代理间重新分发负载,这很有用。要做到这一点,您必须创建一个分区重新分配计划,通过更改副本顺序为每个分区指定新的首选领导。
- 更改日志目录以使用特定的 JBOD 卷
- 更改 Kafka 代理的日志目录以使用特定的 JBOD 卷。如果要将 Kafka 数据移到不同的磁盘或存储设备中,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,该计划为每个主题指定新日志目录。
15.1.1. 生成分区重新分配计划
分区重新分配工具(kafka-reassign-partitions.sh
)通过生成分区分配计划来工作,指定应将哪些分区从当前代理移到新代理中。
如果您对计划满意,您可以执行它。然后,该工具执行以下操作:
- 将分区数据迁移到新代理
- 更新 Kafka 代理上的元数据以反映新分区分配
- 触发 Kafka 代理的滚动重启,以确保新分配生效
分区重新分配工具有三个不同的模式:
--generate
- 取一组主题和代理,并生成 重新分配 JSON 文件,这会导致将这些主题的分区分配给这些代理。由于这对整个主题进行操作,因此当您只需要重新分配某些主题的一些分区时,无法使用它。
--execute
- 取一个 重新分配 JSON 文件,并将其应用到集群中的分区和代理。因此,获得分区的代理遵循分区领导机。对于给定分区,当新代理发现并加入 ISR (同步副本)后,旧代理将停止为后续,并将删除其副本。
--verify
-
使用与
--execute
步骤相同的 重新分配 JSON 文件,--verify
会检查文件中所有分区是否已移至其预期的代理中。如果重新分配已完成,--verify
也会删除任何生效的流量节流(--throttle
)。除非被删除,throttles 将继续影响集群,即使重新分配完成后也是如此。
在任何给定时间,集群中只能有一个重新分配运行,且无法取消正在运行的重新分配。如果需要取消重新分配,请等待它完成,然后执行另一个重新分配来恢复第一个重新分配的影响。kafka-reassign-partitions.sh
将打印这个 reversion 的重新分配 JSON 作为其输出的一部分。非常大的重新分配应该被分解为多个较小的重新分配,以防需要停止 in-progress 重新分配。
15.1.2. 在分区重新分配 JSON 文件中指定主题
kafka-reassign-partitions.sh
工具使用一个重新分配 JSON 文件,该文件指定要重新分配的主题。如果要移动特定分区,您可以生成重新分配 JSON 文件或手动创建文件。
一个基本的重新分配 JSON 文件在以下示例中显示结构,它描述了属于两个 Kafka 主题的三个分区。每个分区都会被重新分配给一组新的副本,这些副本由代理 ID 识别。版本
、topic
、分区
、和 replicas
属性都是必需的。
分区重新分配 JSON 文件结构示例
{ "version": 1, 1 "partitions": [ 2 { "topic": "example-topic-1", 3 "partition": 0, 4 "replicas": [1, 2, 3] 5 }, { "topic": "example-topic-1", "partition": 1, "replicas": [2, 3, 4] }, { "topic": "example-topic-2", "partition": 0, "replicas": [3, 4, 5] } ] }
不包含在 JSON 中的分区不会改变。
如果您只使用主题数组指定 主题
,分区重新分配工具会重新分配属于指定主题的所有分区。
为主题重新分配所有分区的重新分配 JSON 文件结构示例
{ "version": 1, "topics": [ { "topic": "my-topic"} ] }
15.1.3. 在 JBOD 卷间重新分配分区
当在 Kafka 集群中使用 JBOD 存储时,您可以在特定卷及其日志目录间重新分配分区(每个卷只有一个日志目录)。
要将分区重新分配给特定卷,请在重新分配 JSON 文件中为每个分区添加 log_dirs
值。每个 log_dirs
数组包含与 replicas
数组相同的条目数,因为每个副本都应分配给特定的日志目录。log_dirs
数组包含一个到日志目录的绝对路径或特殊值 any
。any
值表示 Kafka 可以为该副本选择任何可用的日志目录,这在 JBOD 卷间重新分配分区时很有用。
使用日志目录重新分配 JSON 文件结构示例
{ "version": 1, "partitions": [ { "topic": "example-topic-1", "partition": 0, "replicas": [1, 2, 3] "log_dirs": ["/var/lib/kafka/data-0/kafka-log1", "any", "/var/lib/kafka/data-1/kafka-log2"] }, { "topic": "example-topic-1", "partition": 1, "replicas": [2, 3, 4] "log_dirs": ["any", "/var/lib/kafka/data-2/kafka-log3", "/var/lib/kafka/data-3/kafka-log4"] }, { "topic": "example-topic-2", "partition": 0, "replicas": [3, 4, 5] "log_dirs": ["/var/lib/kafka/data-4/kafka-log5", "any", "/var/lib/kafka/data-5/kafka-log6"] } ] }
15.1.4. 分区重新分配节流
分区重新分配可能会是一个较慢的过程,因为它涉及在代理间传输大量数据。为了避免对客户端产生不利影响,您可以限制重新分配过程。使用带有 kafka-reassign-partitions.sh
工具的 --throttle
参数,以节流重新分配。您可以为代理间移动分区指定每秒的最大阈值(以字节为单位)。例如,-- throttle 5000000
为移动分区设置 50 MBps 的最大阈值。
节流可能会导致重新分配完成所需的时间。
- 如果节流过低,则新分配的代理将无法与要发布的记录保持同步,且重新分配永远不会完成。
- 如果节流过高,客户端将会受到影响。
例如,对于生成者,这可能比等待确认的正常延迟高。对于消费者,这可能因为轮询之间延迟更高的吞吐量导致的吞吐量下降。