基本概念

1、一个consumer group中有多个consumer组成,一个topic有多个partition组成,现在的问题是,==到底由哪个consumer来消费哪个partition的数据==。
2、Kafka有四种主流的分区分配策略:==Range、RoundRobin、Sticky、CooperativeSticky==。
可以通过配置参数partition.assignment.strategy,修改分区的分配策略。默认策略是Range+CooperativeStickyKafka可以同时多个分区分配策略

分区分配策略之Range

Range 是对每个topic 而言的。

1、首先对同一个topic里面的==分区按照序号进行排序==,并对==消费者按照字母顺序进行排序==。

2、假如现在有7个分区,3个消费者,排序后的分区将会是0,1,2,3,4,5,6;消费者排序完之后将会是CO,C1,C2。

3、通过 ==partitions数/consumer数== 来决定每个消费者应该消费几个分区。==如果除不尽,那么前面几个消费者将会多消费1个分区==。例如:7/3=2余1,除不尽,那么消费者C0便会多消费1个分区。8/3=2余2,除不尽,那么C0和C1 分别多消费一个。

4、==注意==:如果只是针对1个topic而言,C0消费者多消费1个分区影响不是很大。但是如果有N多个topic,那么针对每个topic,消费者C0都将多消费1个分区,topic越多,C0消费的分区会比其他消费者明显多消费N个分区。
==容易产生数据倾斜!==

消费者下线及再平衡

如果消费者组中的某个消费者45s都没有消费分配给他的分区的数据,45s之后这个消费者的所有分区全部由消费者组中的任一个消费者==整体消费==。例如:A消费者消费主题中的0,1,2分区,如果A挂了,那么45s后将由B消费者消费0,1,2分区的数据(B消费者在这45s中正常消费自己对应的分区的数据)。

之后进行再平衡,将主题中的分区按照分配策略分配给消费者组剩下的消费者进行消费。

分区分配策略之RoundRobin

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

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

20220423110406.png

分配策略的全类名可以去官网找:https://kafka.apache.org/30/documentation.html 搜索 partition.assignment.strategy

20220423110653.png

消费者下线及再平衡

如果消费者组中的某个消费者45s都没有消费分配给他的分区的数据,45s之后这个消费者需要消费的分区将==按照轮训策略分配给其他的消费者进行消费==。例如: A消费者消费0,1,2分区,当A消费者挂了,还有B消费者和C消费者正常运行,45s后,就变成了B消费0和2分区中的数据(B原有消费的分区不变,正常消费),C消费1分区(B消费0分区,C消费1分区,B消费2分区)。

之后进行再平衡按照策略将分区和消费者的关系重新划分。

分区分配策略之Sticky

粘性分区定义: 可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前,考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。

粘性分区是Kafka从0.11.x版本开始引入这种分配策略,==首先会尽量均衡的放置分区到消费者上面==,在出现同一消费者组内消费者出现问题的时候,会==尽量保持原有分配的分区不变化==。

消费者下线及再平衡

如果消费者组中的某个消费者45s都没有消费分配给他的分区的数据,45s之后这个消费者需要消费的分区将==按照尽量均匀的分配给其他的消费者进行消费==。例如: A消费者消费0,1,2分区,当A消费者挂了,还有B消费者和C消费者正常运行,45s后,就变成了B消费0和2分区中的数据(B原有消费的分区不变,正常消费),C消费1分区(A的分区==尽量均匀随机==的分配给其他消费者,不再是轮询的方式了)。

之后再按照分配策略重新分配,==但是会尽量保持原有分配的分区不变化==。