分区迁移

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

从分区分配信息可知,已按照分区重分配方案完成了分区迁移。