kafka topic分区分配机制


发布于 2024-04-03 / 34 阅读 / 0 评论 /
kafka在创建topic时,分区在哪个data目录下的分配机制

1.分区策略

分区分配策略时在创建topic时进行的,创建topic的过程可参考《Kafka创建topic过程》。

这里涉及到分区副本分配到broker上,以及副本目录分配到具体的磁盘目录。

1.1.分区副本与broker

分区副本的分配需要考虑到机架的因素。

如果所有的broker处于同一机架上,分配策略如下:

broker列表,记为brokerArray
获取第一个分区的第一个副本所在brokerArray中的偏移量,startIndex,小于brokerArray大小的随机整数。
获取下一个副本转移的系数nextReplicaShift,小于brokerArray大小的随机整数。
遍历每个分区,分区号(partitionId)从0开始,进行以下处理
    第一个副本,分配的broker为index = (partitionId + startIndex) % brokerArray.size 
    其余副本所在broker index=(lastIndex + nextReplicaShift) % brokerArray.size。lastIndex表示上一个副本的broker index。
    分配完brokerArray数量的分区数后,nextReplicaShift做加一操作。比如10个分区,3个broker,则3、6、9号分区处理的时候,都要对nextReplicaShift+1

如果broker位于不同的机架上,分配策略如下:

把broker根据rack进行分组,记为brokerRackMap
将所有的broker进行排序,先根据每个rack中的broker索引排序,再根据rackId进行排序。记为arrangedBrokerList
遍历每个分区,分区号(partitionId)从0开始,进行以下处理
    第一个副本,分配的broker为index = (partitionId + startIndex) % arrangedBrokerList.size
    其余副本所在broker与已分配的副本不在同一个rack中,除非所有的rack中都已分配了该分区的副本。

本质上也是在机架层面的负载均衡(副本数,而非副本中数据量大小)。

1.2.分区副本与磁盘目录

kafka可通过配置logs.dirs来配置多块磁盘作为数据目录,创建分区副本时,磁盘目录的选择逻辑如下:

对活跃数据目录下的分区进行计数比较,选择分区数最少的数据目录,并创建对应的分区目录以及分区元数据。

这里也做到了数据目录的负载均衡(副本数,而非副本中数据量大小)。

2.kafka设计层面对负载均衡的解释

通过以上源码级的机制解读,我们发现以下两点:

(1)kafka当前只针对分区副本数量上的负载均衡,把分区副本均衡地分配到各个broker,以及均衡到各个机架上,不会考虑到某个broker有更多的或更少的分区副本。这种负载均衡可以用一句话来解释:新增一个topic时,任何一个broker都有相等的概率获取到分区的分配,且获取到的分区数期望都是相等的。

(2)kafka无法实现针对数据存储上的负载均衡,每次分配磁盘时,会当前分区数最少的数据目录进行分配,也就是要考虑到历史分区副本数,但也仅局限于“分区副本数”,而不是“分区副本占用空间的大小”。

那么kafka当前设计的初衷是什么呢?

kafka作为一个中间件,不是一个数据库,不会对数据进行长久保留,更多情况是定时清理,而数据占用存储空间的大小在这种动态清理机制作用下会存在不确定性,那么根据数据存储空间大小来分配分区副本成本就会非常高,真正意义上的事倍功半。而分区副本数相对来说是确定的,当前kafka的整套元数据体系都是根据确定性的数据来设计的,这也是为什么可以做到分区副本数均衡的原因。

3.如何实现数据存储级的负载均衡

如果原生kafka无法实现数据存储空间的负载均衡,那么有什么补偿措施呢?答案是有的,kafka提供这种补偿机制。

3.1.业务侧实现数据负载均衡

producer侧有一个partitioner.class参数,指定每条消息按照什么样的策略分配到对应的分区上,可自定义实现数据均匀分配到各个broker上。

同时,要满足一个条件,副本数 = N broker数 每个broker挂载磁盘数。

举例来说,如果kafka集群有3个broker,每个broker挂载4块盘,那么新建topic的分区副本数必须为12的倍数,才能实现数据均衡。

然后,如果所有的topic都实现数据均衡,那么整个kafka集群就实现了数据均衡。

3.2.通过运维手段实现数据负载均衡

kafka提供kafka-reassign-partitions.sh工具实现分区重分布操作,当运维侧发现有数据倾斜,可把分区和副本按照自己的观测数据进行分区重分布操作,这种操作是磁盘级别的,可把副本从资源紧张的broker磁盘迁移到资源空闲的broker磁盘。