22 分区重分配

重新分配分区在broker中的分布

当集群中一个节点突然宕机,如果节点上的分区是单副本,那么这些分区就会变的不可用;如果是多副本,那么此节点上的leader副本就会转变到对应的follower副本中。总之,节点宕机那么节点上的分区副本都会处于失效状态,Kafka 并不会将不能用的节点中的副本迁移至可用节点当中,如果放任不管,不仅会影响整个集群的负载均衡,还会影响整体服务的可用性和可靠性。

当要对一个集群中的某个节点有计划下线操作时,为了保证分区及副本的合理分配,我们可以通过某种方式将节点上的分区副本迁移到其他可用的节点上。
当集群新增 broker 节点时,只有新创建主题的分区才会分配到新增的 broker 节点,原来主题的分区还是在原来节点,这样就造成了节点负载不均衡。
为了解决上述问题,需要让分区副本再次进行合理分配,也就是所谓的分区重分配。Kafka 提供了 Kafka-reassign-partitions.sh 脚本来执行分区重分配的工作,可以在集群扩容、broker节点失效的情况下对分区进行迁移。

使用步骤:

  1. 创建包含主题清单的 JSON 文件。
  2. 根据主题清单和 broker 节点清单生成一份重新分配方案。
  3. 根据方案执行分配计划

示例:
首先,在由三个节点组成的集群中创建一个主题,主题包含4个分区和2个副本

 bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --create --topic topic-reassign --replication-factor 2 --partitions 4

# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-reassign
Topic:topic-reassign	PartitionCount:4	ReplicationFactor:2	Configs: 
    Topic: topic-reassign	Partition: 0	Leader: 0	Replicas: 0,2	Isr: 0,2
    Topic: topic-reassign	Partition: 1	Leader: 1	Replicas: 1,0	Isr: 1,0
    Topic: topic-reassign	Partition: 2	Leader: 2	Replicas: 2,1	Isr: 2,1
    Topic: topic-reassign	Partition: 3	Leader: 0	Replicas: 0,1	Isr: 0,1

比如需要下线 brokerId 为1的节点。创建JSON文件,名称为reassign.jso,内容为要进行分区重分配的主题清单。

{
        "topics":[
                {
                        "topic":"topic-reassign"
                }
        ],
        "version":1
}

第二步,根据JSON文件和指定所要分配的 broker 节点列表来生成一份候选的重新分配方案

# bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --generate --topics-to-move-json-file reassign.json --broker-list 0,2
Current partition replica assignment
{"version":1,"partitions":[{"topic":"topic-reassign","partition":2,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":1,"replicas":[1,0],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":3,"replicas":[0,1],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":0,"replicas":[0,2],"log_dirs":["any","any"]}]}

Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"topic-reassign","partition":2,"replicas":[2,0],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":1,"replicas":[0,2],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":3,"replicas":[0,2],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":0,"replicas":[2,0],"log_dirs":["any","any"]}]}

上面的示例中包含4个参数,其中 zookeeper 用来指定 ZooKeeper 的地址。generate 是 kafka-reassign-partitions.sh 脚本中指令类型的参数,可以类比于 kafka-topics.sh 脚本中的 create、list 等,它用来生成一个重分配的候选方案。topic-to-move-json 用来指定分区重分配对应的主题清单文件的路径,该清单文件的具体的格式可以归纳为{“topics”: [{“topic”: “foo”},{“topic”: “foo1”}],“version”: 1}。broker-list 用来指定所要分配的 broker 节点列表,比如示例中的“0,2”。

上面示例中打印出了两个 JSON 格式的内容。第一个“Current partition replica assignment”所对应的 JSON 内容为当前的分区副本分配情况,在执行分区重分配的时候最好将这个内容保存起来,以备后续的回滚操作。第二个“Proposed partition reassignment configuration”所对应的 JSON 内容为重分配的候选方案,注意这里只是生成一份可行性的方案,并没有真正执行重分配的动作。生成的可行性方案的具体算法和创建主题时的一样,这里也包含了机架信息,具体的细节可以参考17节的内容。
我们需要将第二个 JSON 内容保存在一个 JSON 文件中,假定这个文件的名称为 project.json。

第三步,执行具体分配方案

# bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --execute --reassignment-json-file project.json 
Current partition replica assignment

{"version":1,"partitions":[{"topic":"topic-reassign","partition":2,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":1,"replicas":[1,0],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":3,"replicas":[0,1],"log_dirs":["any","any"]},{"topic":"topic-reassign","partition":0,"replicas":[0,2],"log_dirs":["any","any"]}]}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions.

我们再次查看主题 topic-reassign 的具体信息:

]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-reassign
Topic:topic-reassign	PartitionCount:4	ReplicationFactor:2	Configs: 
    Topic: topic-reassign	Partition: 0	Leader: 0	Replicas: 2,0	Isr: 0,2
    Topic: topic-reassign	Partition: 1	Leader: 0	Replicas: 0,2	Isr: 0,2
    Topic: topic-reassign	Partition: 2	Leader: 2	Replicas: 2,0	Isr: 2,0
    Topic: topic-reassign	Partition: 3	Leader: 0	Replicas: 0,2	Isr: 0,2

可以看到主题中的所有分区副本都只在0和2的 broker 节点上分布了。

在第三步的操作中又多了2个参数,execute 也是指令类型的参数,用来指定执行重分配的动作。reassignment-json-file 指定分区重分配方案的文件路径,对应于示例中的 project.json 文件。

除了让脚本自动生成候选方案,用户还可以自定义重分配方案,这样也就不需要执行第一步和第二步的操作了

分区分配的基本原理先通过控制器为每个分区添加副本(新增副本因子数),新的副本将从 leader 副本复制数据,因为每个分区数据量不同,复制的时间将不同。在完成复制后,控制器将旧副本从副本清单移除(恢复原先副本因子数)。所以要注意在重新分配的过程中要保证有足够的空间
细心的读者可能观察到主题 topic-reassign 中有3个 leader 副本在 broker 0 上,而只有1个 leader 副本在 broker 2 上,这样负载就不均衡了。不过我们可以借助上一节中的 kafka-perferred-replica-election.sh 脚本来执行一次优先副本的选举动作,之后可以看到主题 topic-reassign 的具体信息已经趋于完美:

# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-reassign
Topic:topic-reassign	PartitionCount:4	ReplicationFactor:2	Configs: 
    Topic: topic-reassign	Partition: 0	Leader: 2	Replicas: 2,0	Isr: 0,2
    Topic: topic-reassign	Partition: 1	Leader: 0	Replicas: 0,2	Isr: 0,2
    Topic: topic-reassign	Partition: 2	Leader: 2	Replicas: 2,0	Isr: 2,0
    Topic: topic-reassign	Partition: 3	Leader: 0	Replicas: 0,2	Isr: 0,2

对于分区重分配而言,这里还有可选的第四步操作,即验证查看分区重分配的进度。只需将上面的 execute 替换为 verify 即可,具体示例如下:

# bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --verify --reassignment-json-file project.json 
Status of partition reassignment: 
Reassignment of partition topic-reassign-2 completed successfully
Reassignment of partition topic-reassign-1 completed successfully
Reassignment of partition topic-reassign-3 completed successfully
Reassignment of partition topic-reassign-0 completed successfully

分区重分配对集群的性能有很大的影响,需要占用额外的资源,比如网络和磁盘。在实际操作中,我们将降低重分配的粒度,分成多个小批次来执行,以此来将负面的影响降到最低,这一点和优先副本的选举有异曲同工之妙。 还需要注意的是,如果要将某个 broker 下线,那么在执行分区重分配动作之前最好先关闭或重启 broker。这样这个 broker 就不再是任何分区的 leader 节点了,它的分区就可以被分配给集群中的其他 broker。这样可以减少 broker 间的流量复制,以此提升重分配的性能,以及减少对集群的影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值