分区迁移
1、节点下线分区迁移
首先,执行以下命令创建一个主题。
kafka-topics.sh --create --zookeeper 172.20.10.3:2181,172.20.10.4:2181,172.20.10.5:2181 --replication-factor 1 --partitions 3 --topic reassign-partitions
Created topic "reassign-partitions".
该主题分区副本分布情况如下:
kafka-topics.sh --describe --zookeeper 172.20.10.3:2181,172.20.10.4:2181,172.20.10.5:2181 --topic reassign-partitions
Topic:reassign-partitions PartitionCount:3 ReplicationFactor:1 Configs:
Topic: reassign-partitions Partition: 0 Leader: 1 Replicas: 1 Isr: 1
Topic: reassign-partitions Partition: 1 Leader: 2 Replicas: 2 Isr: 2
Topic: reassign-partitions Partition: 2 Leader: 0 Replicas: 0 Isr: 0
然后,假设需要将 brokerid=1 的节点下线,在下线前我们通过Kafka提供的 kafka-reassign-partitions.sh 脚本按以下步骤将该分区转移到其他节点上。
(1) 生成分区分配方案。首先创建一个文件,该文件以JSON字符串格式指定要进行分区重分配的主题。例如,我在$KAFKA_HOME/config 目录下创建一个名为topics-to-move.json的文件,若要对多个主题分区重新分配,则以JSON格式指定多组“topic”,version为固定值。
{"topics":
[{"topic":"reassign-partitions"}],
"version": 1
}
然后执行以下生成分区分配方案的命令。
kafka-reassign-partitions.sh --zookeeper 172.20.10.3:2181,172.20.10.4:2181,172.20.10.5:2181 --topics-to-move-json-file ../config/topics-to-move.json --broker-list "0,2" --generate
该命令的各个参数说明如下。
- zookeeper:指定ZooKeeper地址,从ZooKeeper获取主题元数据信息。
- topics-to-move-json-file:指定分区重分配对应的主题配置文件的路径,该配置文件的内容为以JSON格式指定需要进行分区重分配的主题。
- broker-list:指定分区可迁移的brokerid列表。本例是要下线brokerid为1的节点,需要将该节点的分区迁移到0个2的节点上,因此这里指定brokerid的列表为“0,2”。
- generate:指定该命令类型为生成一个分区分配的参考配置。
该命令底层实现原理为:从ZooKeeper中读取主题元数据信息及指定的有效代理,根据分区副本分配算法重新计算指定主题的分区副本分配方案。
生成分区分配方案的命令执行后在控制台输出信息如下:
Current partition replica assignment
{"version":1,"partitions":[{"topic":"reassign-partitions","partition":0,"replicas":[1],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":1,"replicas":[2],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":2,"replicas":[0],"log_dirs":["any"]}]}
Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"reassign-partitions","partition":0,"replicas":[2],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":1,"replicas":[0],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":2,"replicas":[2],"log_dirs":["any"]}]}
以上信息包括两部分:当前分区分配信息以及根据指定的代理列表生成的分区分配方案。Kafka推荐的分配方案已将3个分区分别分配到brokerid为0和2的两节点上。将Kakfa生成的分区重分配方案信息复制到$KAFKA_HOME/config 目录下 partitions-reassignment.json 文件中。
(2)执行分区迁移。通过步骤1生成了分区新的分配方案,执行以下命令对指定主题的分区进行迁移:
kafka-reassign-partitions.sh --zookeeper 172.20.10.3:2181,172.20.10.4:2181,172.20.10.5:2181 --reassignment-json-file ../config/partitions-reassignment.json --execute
Current partition replica assignment
{"version":1,"partitions":[{"topic":"reassign-partitions","partition":0,"replicas":[1],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":1,"replicas":[2],"log_dirs":["any"]},{"topic":"reassign-partitions","partition":2,"replicas":[0],"log_dirs":["any"]}]}
Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions.
该命令的各个参数说明如下。
- zookeeper:指定ZooKeeper 地址,该命令会将新的分区分配方案信息写入ZooKeeper相应节点。
- reassignment-json-file:指定分区分配方案的文件路径,该分配文件是以JSON格式指定各分区对应的brokerid列表。
- execute:指定该命令操作类型为执行分区迁移。
分区迁移的基本原理是在目标节点上创建分区目录,然后复制原分区数据到目标节点,最后删除原节点的数据,因此在迁移时要确保目标节点有足够的空间。
(3)查看分区迁移进度。执行以下命令查看分区迁移的进度:
kafka-reassign-partitions.sh --zookeeper 172.20.10.3:2181,172.20.10.4:2181,172.20.10.5:2181 --reassignment-json-file ../config/partitions-reassignment.json --verify
Status of partition reassignment:
Reassignment of partition reassign-partitions-0 completed successfully
Reassignment of partition reassign-partitions-1 completed successfully
Reassignment of partition reassign-partitions-2 completed successfully
从分区迁移进度信息可知:3个分区已完成迁移,若分区正在迁移中,则状态为in progress。分区迁移一旦开始即无法停止,更不要强行停止集群,否则会造成数据不一致。
(4)再次查看分区分配信息:
Topic:reassign-partitions PartitionCount:3 ReplicationFactor:1 Configs:
Topic: reassign-partitions Partition: 0 Leader: 2 Replicas: 2 Isr: 2
Topic: reassign-partitions Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: reassign-partitions Partition: 2 Leader: 2 Replicas: 2 Isr: 2
从分区分配信息可知,已按照分区重分配方案完成了分区迁移。