赞
踩
kafka内部的分区管理可以从几个方面去介绍。
1、优先副本的选举
2、分区重新分配
3、复制限流
4、修改副本因子
优先副本选举主要是为了让所有的分区尽可能分布在不同的broker上的一种机制,那么什么是优先副本?优先副本是AR种的第一个副本,这个副本通常为leader,假如这个副本不是leader,那么这个副本就是非优先副本。
假如我们通过以下方式创建一个topic_a,分区数为3,副本因子也为3.
/kafka-topics.sh --create --zookeeper localhost:2181 --partitions 3 --replication-factor 1 --topic topic_a
最终创建的的结果如下
partition | leader(broker-id) | AR(broker-ids) | ISR(broker-ids) |
---|---|---|---|
0 | 1 | [1,2,0] | [1,2,0] |
1 | 2 | [2,0,1] | [2,0,1] |
2 | 0 | [0,1,2] | [0,1,2] |
假如由于2号broker宕机或者其它情况导致1号分区的leader变得不可用,此时重新选举了一个leader在0-broker上,那么结果如下。
partition | leader(broker-id) | AR(broker-ids) | ISR(broker-ids) |
---|---|---|---|
0 | 1 | [1,2,0] | [1,2,0] |
1 | 0 | [2,0,1] | [0,1,2] |
2 | 0 | [0,1,2] | [0,1,2] |
此时0号broker上的leader数量为2个,这个节点负载此时最高,1号节点的负载最低,之前的负载均衡变成了现在的负载失衡,理想状态下优先副本应该就是该分区的leader副本,而优先副本的选举就是尽可能的将每个分区的leader副本作为优先副本,从而促进集群的负载均衡,但是真正的负载均衡还得参考每个leader的数据传输负载
在kafka中默认有一个参数控制自动优先副本的选举auto.leader.rebalance.enable=true
,这个选举机制的间隔时间通过leader.imbalance.check.interval.seconds
参数进行控制,默认是5分钟(300s)一次,这个选举机制的衡量标准是通过“broker不平衡率”,broker不平衡率=非优先副本的leader个数/总分区数
,假如该值超过leader.imbalance.per.broker.percentage,默认为10%
,那么就开始进行优先副本的选举。上面案例的不平衡率=1/3=33%。
记住,在实际上产中是不会开启优先副本选举的,因为可能引起负面的性能问题,比如客户端请求阻塞,所以一般还是通过监控+手动控制优先副本的方式来控制集群负载,手动控制通过bin/kafka-preferred-replica-election.sh --zookeeper localhost:2181/kafka --path-to-json-file election.json
命令进行。
#election.json文件内容示例如下。选举操作应该避开业务高峰期进行,这个--path-to-json-file选项是可选的,但是强烈建议加上这个配置。 { "partitions":[ { "partition":0, "topic":"topic-partitions" }, { "partition":1, "topic":"topic-partitions" }, { "partition":2, "topic":"topic-partitions"} ] }
分区重新分配,主要是在需要进行横向扩展Broker的时候或者有计划下线Broker的时候使用,假如在Kafka集群中新加入了一个Broker,那么只有新增的topic对应的分区才会分配到该节点上,之前的topic数据是不会分配给该节点的,这就导致了新增节点与原先节点数据的严重不均衡,所以kafka提供了kafka-reassign-partitions.sh
脚本,在节点扩展、Broker下线的时候通过数据复制的方式重新分配分区,该脚本的使用分3个步骤:
假设现在有3个节点,0,1,2,我们想要下线Broker1,然后再重新分配。
第一步,创建一个主题清单的json文件:reassign.json
{
"topics":[
{
"topic": "topic-a"
}
],
"version": 1
}
第二步,根据主题清单创建一个重新分配的方案,这个方案可以自己通过json的schema创建,这样第一步、第二步操作就省去了。
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保存下来用来做操作的回滚。
#Current partition replica assignment
{"version":1,"partitions":[]}
#Proposed partition reassignment configuration
{"version":1,"partitions":[]}
第三步,执行重新分配方案
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --execute --reassign-json-file project.json
#校验改重新方案的执行情况
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --varify --reassign-json-file project.json
如果需要将某个Broker下线,那么在执行重新分配方案的时候,最好先关闭或者重启Broker,这样Broker就不再是任何分区的leader节点了,这样它的分区就可以被分配给集群中的其它Broker,这样可以减少集群间的流量复制,提升重新分配的性能,以减少对整个集群的影响。
主题分区的重新分配是通过数据复制来实现的,首先创建新副本、同步数据、删除旧副本;
数据复制会占用额外的资源,如果复制的量太大,势必会影响整体的性能,尤其是在业务高峰期的时候,减小重分配的粒度、以小批次的方式可行,如果集群中某个主题或某个分区 的流量在某段时间内特别大,那么只靠减小粒度是不足以应对的,这时就需要有个限流的机制,可以对副本之间的复制流量加以限制,保证整体不受太大的影响。
副本间的复制限流有2种方式:
kafka-config.sh
#添加配置 bin/kafka-configs.sh --zookeeper localhost:2181/kafka --entity-type brokers --entity-name 1 --alter --add-config follower.replication.throttled.rate=l024 , leader.replication.throttled.rate=l024 #查看配置 bin/kafka-configs.sh --zookeeper localhost:2181/kafka --entity-type brokers --entity-name 1 --describe #删除配置 bin/kafka-configs.sh --zookeeper localhost:2181/kafka --entity-type brokers --entity-name 1 --alter --delete-config follower.replication.throttled.rate=l024 , leader.replication.throttled.rate=l024
#1、首先创建一个主题topic-throttled,partitions=3,replication-factor=2
bin/kafka-topics.sh --create --zookeeper localhost:2181 --partitions 3 --replication-factor 2 --topic topic-throttled
#2、查看创建的topic的详情
bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic topic-throttled
#3、添加限制复制流量的配置
bin/kafka-config.sh
--zookeeper localhost:2181/kafka
--entity-type topics
--entity-name topic-throttled
--alter
--add-config
leader.replication.throttled.replicas=[0:0,1:1,2:2],follower.replication.throttled.replicas=[0:1,1:2,2:0] #其中0:0等代表分区号与代理的映射关系
kafka-reassign-partitions.sh
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --execute --reassign-json-file project.json --throttled 10 # 这里的10表示10B/S
期望的重新分配之后的结果如下,假装broker-1此时下线:
Partition | 重新分配之前AR | 预期重新分配之后AR |
---|---|---|
0 | 0,1 | 0,2 |
1 | 1,2 | 2,0 |
2 | 2,0 | 0,2 |
最终我们发现只需要重新分配0,1分区与代理的映射,分区2的AR是没有变化的。
1、首先获取限流的副本列表
#对于分区0
leader.replication.throttled.replicas=[0:0,0:1]
follower.replication.throttled.replicas=[0:2]
#对于分区1
leader.replication.throttled.replicas=[1:1,1:2]
follower.replication.throttled.replicas=[1:0]
#对于分区2
分区2的AR集合没有变化,这里忽略
2、执行限制复制流量具体操作
bin/kafka-config.sh
--zookeeper localhost:2181/kafka
--entity-type topics
--entity-name topic-throttled
--alter
--add-config
leader.replication.throttled.replicas=[0:0,0:1,1:1,1:2],follower.replication.throttled.replicas=[0:2,1:0]
3、接下来限制broker-2的复制速率为10B/S
bin/kafka-configs.sh
--zookeeper localhost:2181/kafka
--entity-type brokers
--entity-name 2
--alter
--add-config
follower.replication.throttled.rate=l0 , leader.replication.throttled.rate=l0
4、在执行重新分配分区之前,需要开启一个Producer并向topic-throttled中发一批消息,这样便于观察正在复制数据的过程
./kafka-console-producer.sh --broker-list localhost:9092 --topic topic-throttled
> my pl is a bxxch
> yeah he is so fxking disgusting
.....
5、然后开始执行分区重新分配的操作
#假如这里你自己创建了一个分区分配的方案project.json
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --execute --reassign-json-file project.json
#校验改重新方案的执行情况
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181/kafka --varify --reassign-json-file project.json
root:$/> “Throttle was removed.”#表示之前针对限流做的配置全部被清除
虽然有2种限流的方式,但是还是建议使用bin/kafka-reassign-partitions.sh --throttled 1024的方式
,方便简单,不容易出错
zkCli.sh
> get /config/topics/topic-throttled
{
"version":1 ,
"config":
{
"follower.replication.throttled.replicas":"1:0,0:2",
"leader.replication.throttled.replicas":"1:1,1:2"
}
}
首先可以观察重分配的方案project.json的内容,我们可以在生成方案的时候,手动修改副本因子的个数,与分区的修改不同的是,parttiion在alter的时候只能增加不能减少,但是replicas是可以减少的
#初始方案 { "topic":"topic-throttled" "partition":1 "replicas":[ 2, 0 ], "log_dirs":[ "any", "any" ] } #修改副本因子的方案,在broker上增加1个分区1的副本 { "topic":"topic-throttled" "partition":1 "replicas":[ 2, 1, 0 ], "log_dirs":[ "any", "any", "any" ] }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。