第 12 章 使用分区重新分配工具
在扩展 Kafka 集群时,您可能需要添加或删除代理并更新分区分布或主题复制因素。要更新分区和主题,您可以使用 kafka-reassign-partitions.sh
工具。
AMQ Streams Cruise Control 集成或主题 Operator 支持更改主题的复制因素。但是,您可以使用 kafka-reassign-partitions.sh
工具更改主题的复制因素。
该工具也可用于重新分配分区并在代理间平衡分区分布,以提高性能。但是,建议使用 Cruise Control 自动分区重新分配和集群重新平衡。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。
建议将 kafka-reassign-partitions.sh
工具作为单独的交互式 pod 运行,而不是在代理容器中运行。在代理容器中运行 Kafka bin/
脚本可能会导致 JVM 从与 Kafka 代理相同的设置开始,这可能会导致中断。在单独的 pod 中运行 kafka-reassign-partitions.sh
工具,您可以避免出现这个问题。使用 -ti
选项运行 pod,创建一个交互式 pod,并在 pod 中运行 shell 命令。
使用终端运行交互式 pod
oc run helper-pod -ti --image=registry.redhat.io/amq-streams/kafka-34-rhel8:2.4.0 --rm=true --restart=Never -- bash
12.1. 分区重新分配工具概述
分区重新分配工具提供以下功能来管理 Kafka 分区和代理:
- 重新分发分区副本
- 通过添加或删除代理来扩展集群,并将 Kafka 分区从大量加载的代理移到使用不足的代理。要做到这一点,您必须创建一个分区重新分配计划,以标识要移动的主题和分区以及移动它们的位置。对于这种类型的操作,建议使用 Cruise Control,因为它 自动执行集群重新平衡过程。
- 扩展主题复制因素和缩减
- 增加或减少 Kafka 主题的复制因素。要做到这一点,您必须创建一个分区重新分配计划,以标识分区之间的现有复制分配,以及使用复制因素更改的更新分配。
- 更改首选领导
- 更改 Kafka 分区的首选领导。如果当前首选领导不可用或者您要在集群中在代理间重新分发负载,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,该计划通过更改副本顺序来指定每个分区的新首选领导。
- 将日志目录更改为使用特定的 JBOD 卷
- 将 Kafka 代理的日志目录更改为使用特定的 JBOD 卷。如果要将 Kafka 数据移动到不同的磁盘或存储设备中,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,用于指定每个主题的新日志目录。
12.1.1. 生成分区重新分配计划
分区重新分配工具(kafka-reassign-partitions.sh
)的工作原理,方法是生成一个分区分配计划,指定哪些分区应从其当前代理移到新代理中。
如果您对计划满意,您可以执行它。然后该工具执行以下操作:
- 将分区数据迁移到新代理
- 更新 Kafka 代理的元数据以反映新分区分配
- 触发 Kafka 代理滚动重启,以确保新分配生效
分区重新分配工具有三种不同的模式:
--generate
- 采用一组主题和代理并生成 重新分配 JSON 文件,该文件将导致将这些主题的分区分配给这些代理。由于这在整个主题上运行,因此当您只想重新分配某些主题分区时无法使用它。
--execute
- 采用 重新分配 JSON 文件,并将其应用到集群中的分区和代理。由于因为分区领导者成为分区领导者而获得分区的代理。对于给定分区,新代理发现并加入 ISR (同步副本)后,旧代理将停止后续代理,并删除其副本。
--verify
-
使用与
--execute
步骤相同的 重新分配 JSON 文件,--verify
会检查文件中所有分区是否已移至其预期的代理中。如果重新分配完成,--verify
也会删除所有生效的流量节流(-throttle
)。除非被删除,即使重新分配完成,节流将继续对集群的影响。
在任意给定时间,集群中只能有一个重新分配,且无法取消正在运行的重新分配。如果需要取消重新分配,请等待它完成,然后执行另一个重新分配来恢复第一个重新分配的影响。kafka-reassign-partitions.sh
将打印这个 reversion 的重新分配 JSON 作为其输出的一部分。非常大的重新分配应该被分解为多个较小的重新分配,以防需要停止 in-progress 重新分配。
12.1.2. 在分区重新分配 JSON 文件中指定主题
该工具使用重新分配 JSON 文件,指定要重新分配的主题。如果要移动特定的分区,您可以生成重新分配 JSON 文件或手动创建文件。
重新分配 JSON 文件的结构如下:
{
"version": 1,
"partitions": [
<PartitionObjects>
]
}
其中 <PartitionObjects > 是一个以逗号分隔的对象列表,如下所示:
{ "topic": <TopicName>, "partition": <Partition>, "replicas": [ <AssignedBrokerIds> ] }
以下是一个示例重新分配 JSON 文件,它将主题 topic-a
的分区 4
分配给代理 2
, 4
和 7
;主题 topic-b
的分区 2
分配给代理 1
, 5
和 7
:
分区重新分配文件示例
{ "version": 1, "partitions": [ { "topic": "topic-a", "partition": 4, "replicas": [2,4,7] }, { "topic": "topic-b", "partition": 2, "replicas": [1,5,7] } ] }
未包含在 JSON 中的分区不会改变。
12.1.3. 在 JBOD 卷间重新分配分区
在 Kafka 集群中使用 JBOD 存储时,您可以选择在特定卷及其日志目录间重新分配分区(每个卷都有一个日志目录)。要将分区重新分配给特定卷,请在重新分配 JSON 文件中的 < PartitionObjects& gt; 中添加 log_dirs
选项。
{ "topic": <TopicName>, "partition": <Partition>, "replicas": [ <AssignedBrokerIds> ], "log_dirs": [ <AssignedLogDirs> ] }
log_dirs
对象应包含与 replicas
对象中指定的副本数相同的日志目录数量。该值应该是日志目录的绝对路径,也可以是 任何
关键字。
指定日志目录的分区重新分配文件示例
{ "topic": "topic-a", "partition": 4, "replicas": [2,4,7]. "log_dirs": [ "/var/lib/kafka/data-0/kafka-log2", "/var/lib/kafka/data-0/kafka-log4", "/var/lib/kafka/data-0/kafka-log7" ] }
12.1.4. 分区重新分配节流
分区重新分配可能会是一个较慢的过程,因为它涉及在代理间传输大量数据。为了避免对客户端造成负面影响,您可以节流重新分配过程。使用带有 kafka-reassign-partitions.sh
工具的 --throttle
参数来节流重新分配。您可以为代理之间的分区移动指定每秒的最大阈值(以字节为单位)。例如,-- throttle 5000000
为移动 50 MBps 的分区设置最大阈值。
节流可能会导致重新分配更长的时间完成。
- 如果节流太低,则新分配的代理将无法与发布的记录保持同步,且重新分配永远不会完成。
- 如果节流过高,客户端将会受到影响。
例如,对于生成者,这可能会清单高于等待确认的正常延迟。对于消费者,这可能会导致在轮询之间延迟更高的延迟导致的吞吐量下降。