目录

分区的分配及再平衡

1 分区分配策略之Range

2 分区分配策略之RoundRobin

3 分区分配策略之Sticky


分区的分配及再平衡

一个consumer group中有多个consumer组成,一个topic有多个partition组成,现在的问题是,到底由哪个onsumer来消费哪个partition的数据

Kafka有四种主流的分区分配策略: Range、RoundRobin、Sticky、CooperativeSticky
可以通过配置参数partition.assignment.strategy,修改分区的分配策略。默认策略是Range + CooperativeSticky。Kaka可以同时使用多个分区分配策略。

发生分配的过程在消费者组初始化过程中的第4步leader消费者制定消费方案和第7步中再平衡的过程中,

1 分区分配策略之Range

Range是对单个topic而言的。

首先对同一个topic里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序
假如现在有7个分区,3个消费者,排序后的分区将会是0,1,2,3,4,5,6;消费者排序完之后将会是C0,C1,C2。

通过 partitions数/consumer 数来决定每个消费者应该消费几个分区。如果除不尽,那么前面几个消费者将会多消费1个分区

例如,7/3=2余1,除不尽,那么消费者C0便会多消费1个分区。8/3=2余2,除不尽,那么C0和C1分别多消费一个。

kafka 分区策略源码 kafka分区分配策略有哪些_kafka

注意:如果只是针对1个topic而言,C0消费者多消费1个分区影响不是很天。但是如果有N多个topic,那么针对每个topic,消费者C0都将多消费1个分区,topic越多,C0消费的分区会比其他消费者明显多消费N个分区。除此之外, 如果再C0消费者挂掉之后生产者发送消息(挂掉以后45秒以内),那么本来有C0消费的0,1,2分区会重新分配给下一个序号的消费者(C1)消费。此时生产者再次发送消息(挂掉45秒以后)会触发再平衡,将剩余两个消费者根据range策略再次进行分配。
容易产生数据倾斜!

2 分区分配策略之RoundRobin

RoundRobin针对集群中所有Topic而言。

RoundRobin 轮询分区策略,是把所有的partition和所有的consumer都列出来,然后按照hashcode进行排序,最后通过轮询算法来分配partition给到各个消费者。

kafka 分区策略源码 kafka分区分配策略有哪些_kafka 分区策略源码_02

 修改分区策略代码:

//设置分区分配策略
properties.put(ConsumerConfig.PARTITION_ASSIGIIEINTLSTRATEGY_CONFI, "org.apache.kafka.clients.consumer.RoundRotinassignor");

注意测试时所有的消费者都要配置分配策略。

如果再C0消费者挂掉之后生产者发送消息(挂掉以后45秒以内),那么本来有C0消费的0,1,2分区会重新分配给其他消费者(C1,C2)消费。此时生产者再次发送消息(挂掉45秒以后)会触发再平衡,将剩余两个消费者根据RoundRobin策略再次进行分配。

3 分区分配策略之Sticky

粘性分区定义:可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前,考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。
粘性分区是Kafka 从 0.11.x版本开始引入这种分配策略,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化

//设置分区分配策略
properties.put(ConsumerConfig.PARTITION_ASSIGIIEINTLSTRATEGY_CONFI, "org.apache.kafka.clients.consumer.StickyAssignor");

如果再C0消费者挂掉之后生产者发送消息(挂掉以后45秒以内),那么本来有C0消费的0,1,2分区会重新分配给其他消费者(C1,C2)消费。此时生产者再次发送消息(挂掉45秒以后)会触发再平衡,将剩余两个消费者根据sticky策略再次进行分配。

注意:sticky和RoundRobin的不同点在于:RoundRobin是轮询分配,分配到不同消费者的分区会有一定的规律,sticky更重于均匀分配,分配到不同消费者的分区不一定会有规律。