当集群中的一个节点突然宕机下线时,如果节点上的分区是单副本的,那么这些分区就变得不可用,在节点恢复前,相应的数据也就处于丢失状态;如果节点上的分区是多副本的,那么位于这个节点上的leader副本的角色会转交到集群中的其他follower副本中。总而言之,这个节点上的分区副本都已经处于功能失效状态。kafka并不会将这些失效的副本自动地迁移到集群中剩余的可用broker节点上。如果放任不管则不仅影响整个集群的均衡负载,还会影响整体服务的可用性和可靠性。
当要对集群中的一个节点进行有计划的下线操作时,为了保证分区及副本的合理分配,我们也希望通过某种方式能将该节点上的分区副本迁移到其他可用节点上。
当集群中新增broker节点时,只有新创建的主题分区才能被分配到这个节点上,而之前的主题分区并不会自动分配到新加入的节点中,因为它们被创建时还没有这个新节点,这样新节点的负载和原先节点的负载之间严重不均衡。
为了解决上述问题,需要让分区副本再次进行合理的分配,也就是所谓的分区重分配。kafka提供了kafka-reassign-partitions.sh
脚本来执行分区重分配的工作,它可以在集群扩容、broker节点失效的场景下对分区进行迁移。
kafka-reassign-partitions.sh 脚本的使用分为三个步骤:首先创建需要一个包含主题清单的JSON文件,其次根据主题清单和broker节点清单生成一份重分配方案,最后根据这份方案执行具体的重分配动作。
原分区如下,把broker 0停掉
[xuhaixing@hadoop kafka_2.12-2.3.1]$ kafka-topics.sh --zookeeper hadoop:2181/kafka --describe --topic topic-demo02
Topic:topic-demo02 PartitionCount:3 ReplicationFactor:1 Configs:
Topic: topic-demo02 Partition: 0 Leader: 0 Replicas: 0 Isr: 0
Topic: topic-demo02 Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: topic-demo02 Partition: 2 Leader: 2 Replicas: 2 Isr: 2
第一步:创建一个reassign.json的文件
{
"topics":[
{
"topic": "topic-demo02"
}
],
"version":1
}
第二步:根据JSON文件和指定所要分配的broker节点列表来生成一份候选的重分配方案
[xuhaixing@hadoop kafka_2.12-2.3.1]$ kafka-reassign-partitions.sh --zookeeper hadoop:2181/kafka --generate --topics-to-move-json-file reassign.json --broker-list 1,2
Current partition replica assignment
{"version":1,"partitions":[{"topic":"topic-demo02","partition":1,"replicas":[0],"log_dirs":["any"]},{"topic":"topic-demo02","partition":0,"replicas":[0],"log_dirs":["any"]},{"topic":"topic-demo02","partition":2,"replicas":[2],"log_dirs":["any"]}]}
Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"topic-demo02","partition":2,"replicas":[2],"log_dirs":["any"]},{"topic":"topic-demo02","partition":1,"replicas":[1],"log_dirs":["any"]},{"topic":"topic-demo02","partition":0,"replicas":[2],"log_dirs":["any"]}]}
generate
是 kafka-reassign-partitions.sh脚本中指令类型的参数,类似于create、list等,它用来生成一个重分配的候选方案。
topics-to-move-json-file
用来指定分区重分配对应的主题清单文件的路径
broker-list
用来指定所要分配的broker节点列表
上面示例中打印处两个JSON内容,一个是当前分区分配情况,一个是重新分配的候选方案。这里只是生成方案,并没有执行。生成可行性方案的具体算法和创建主题时一样。
将生成的第二个json内容,保存到json文件中,project.json
第三步:执行具体的分配动作
[xuhaixing@hadoop kafka_2.12-2.3.1]$ kafka-reassign-partitions.sh --zookeeper hadoop:2181/kafka --execute --reassignment-json-file project.json
Current partition replica assignment
{"version":1,"partitions":[{"topic":"topic-demo02","partition":1,"replicas":[0],"log_dirs":["any"]},{"topic":"topic-demo02","partition":0,"replicas":[0],"log_dirs":["any"]},{"topic":"topic-demo02","partition":2,"replicas":[2],"log_dirs":["any"]}]}
Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions.
再次查看出题具体信息:
[xuhaixing@hadoop kafka_2.12-2.3.1]$ kafka-topics.sh --zookeeper hadoop:2181/kafka --describe --topic topic-demo02
Topic:topic-demo02 PartitionCount:3 ReplicationFactor:1 Configs:
Topic: topic-demo02 Partition: 0 Leader: 2 Replicas: 2 Isr: 2
Topic: topic-demo02 Partition: 1 Leader: 1 Replicas: 1 Isr: 1
Topic: topic-demo02 Partition: 2 Leader: 2 Replicas: 2 Isr: 2
execute
指令类型参数,用来指定执行重分配的动作
reassignment-json-file
指定分区重分配方案的文件路径
让脚本自动生成候选方案,用户还可以自定义重分配方案,这样也就不需要执行第一步和第二步了。
分区重分配的基本原理是先通过控制器为每个分区添加新副本(增加副本因子) , 新的副 本将从分区的 leader副本那里复制所有的数据。根据分区的大小不同, 复制过程可能需要花一些时间, 因为数据是通过网络复制到新副本上的。在复制完成之后,控制器将旧副本从副本清单里移除(恢复为原先的副本因子数)。注意在重分配的过程中要确保有足够的空间。
可以把execute
改成 verify
查看分区重分配的进度
增加分区
[xuhaixing@xhx151 cluster]$ cat project.json
{"version":1,"partitions":[{"topic":"topic-demo02","partition":2,"replicas":[4,5,3],"log_dirs":["any","any","any"]},{"topic":"topic-demo02","partition":1,"replicas":[5,3,4],"log_dirs":["any","any","any"]},{"topic":"topic-demo02","partition":0,"replicas":[3,4,5],"log_dirs":["any","any","any"]}]}
[xuhaixing@xhx151 cluster]$ kafka-topics.sh --bootstrap-server 192.168.94.151:9093,192.168.94.151:9094,192.168.94.151:9095 --topic topic-demo02 --describe
Topic: topic-demo02 PartitionCount: 3 ReplicationFactor: 2 Configs: segment.bytes=1073741824
Topic: topic-demo02 Partition: 0 Leader: 3 Replicas: 3,4 Isr: 3,4
Topic: topic-demo02 Partition: 1 Leader: 4 Replicas: 4,5 Isr: 5,4
Topic: topic-demo02 Partition: 2 Leader: 5 Replicas: 5,3 Isr: 5,3
[xuhaixing@xhx151 cluster]$ kafka-reassign-partitions.sh --bootstrap-server 192.168.94.151:9093,192.168.94.151:9094,192.168.94.151:9095 --execute --reassignment-json-file project.json
Current partition replica assignment
{"version":1,"partitions":[{"topic":"topic-demo02","partition":0,"replicas":[3,4],"log_dirs":["any","any"]},{"topic":"topic-demo02","partition":1,"replicas":[4,5],"log_dirs":["any","any"]},{"topic":"topic-demo02","partition":2,"replicas":[5,3],"log_dirs":["any","any"]}]}
Save this to use as the --reassignment-json-file option during rollback
Successfully started partition reassignments for topic-demo02-0,topic-demo02-1,topic-demo02-2
[xuhaixing@xhx151 cluster]$ kafka-topics.sh --bootstrap-server 192.168.94.151:9093,192.168.94.151:9094,192.168.94.151:9095 --topic topic-demo02 --describe
Topic: topic-demo02 PartitionCount: 3 ReplicationFactor: 3 Configs: segment.bytes=1073741824
Topic: topic-demo02 Partition: 0 Leader: 3 Replicas: 3,4,5 Isr: 3,4,5
Topic: topic-demo02 Partition: 1 Leader: 4 Replicas: 5,3,4 Isr: 5,4,3
Topic: topic-demo02 Partition: 2 Leader: 5 Replicas: 4,5,3 Isr: 5,3,4
更多优质内容,请关注公众号:程序员星星toC