一个consumer group有多个consumer,一个topic有多个partition,所以必然会涉及到partition的分配问题,即确定哪个partition由哪个consumer来消费。

Kafka有3种分配策略:RangeAssignor、RoundRobinAssignor、StickyAssignor
配置参数:partition.assignment.strategy
image.png

RangeAssignor

org.apache.kafka.clients.consumer.RangeAssignor,即RangeAssignor分配策略,此策略是默认策略

有界范围轮训,主题间partition隔离,按主题内轮训划分。假设存在2个topic,分别有m和n个partition。针对他们的消费组内部各自轮训。即m%k,n%k,此策略的优点是解决了RoundRobin的问题,但缺点是消费者之间的partition数据可能不均匀。

以下是默认情况下的分区分配策略,分配较为均匀
image.png
image.png
image.pngimage.png

在极端情况下,此分区分配策略会出现部分消费者过载的情况:
消费者C0:T0p0、T0p1、T1p0、T1p1
消费者C1:T0p2、T1p2
如果Topic更多的话,消费者消费的分区数更倾斜
image.png

RoundRobinAssignor

org.apache.kafka.clients.consumer.RoundRobinAssignor

消费者订阅相同 Topic
如果同一个消费组内所有的消费者的订阅信息都是相同的,那么RoundRobinAssignor策略的分区分配会是均匀的。

image.png

消费者订阅不同 Topic
假设消费组内有3个消费者C0、C1和C2,它们共订阅了3个主题:t0、t1、t2,这3个主题分别有1、2、3个分区,即整个消费组订阅了t0p0、t1p0、t1p1、t2p0、t2p1、t2p2这6个分区。具体而言,消费者C0订阅的是主题t0,消费者C1订阅的是主题t0和t1,消费者C2订阅的是主题t0、t1和t2,那么最终的分配结果为:

此处难以理解的点在于消费者订阅topic的逻辑,为什么C0只能订阅T0,而C2能订阅T0、T1、T2?

image.png

StickyAssignor

参考

【1】:https://blog.csdn.net/u010022158/article/details/106271208