Kafka 的 Consumer Group 解读

本文探讨了Kafka中的ConsumerGroup如何工作,包括消息分配机制、设计ConsumerGroup的目的以及如何操作ConsumerGroup,强调了其在提高消费吞吐能力和保证消息唯一消费的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为一份笔记,本文再次梳理一下 Kafka 的 Consumer Group。我们知道,一个 Topic 往往会有多个 Partition,一条消息只会被写到一个 Kafka 的 Partition 中,那 Consumer 是怎么消费 Message 的呢? Consumer Group 又从中起到了什么作用呢?

Consumer Group 与 Consumer 到底有何不同?

首先,我们必须要非常清楚地明确一点:Consumer Group 才是消费一个 Topic 的“独立单位”,什么意思呢?就是说:一个 Consumer Group 才是一个通常意义上和 Consumer Client,它下面的 Consumer 实例是作为一个整体消费且只消费一遍 Topic 里的消息,而不是每一个 Consumer 独立消费一遍。当然,如果一个 Consumer Group 只有一个 Consumer,就没有区别了。

这样的话,一个 Consumer Group 下的多个 Consumer 是怎么分配消息的呢?一条消息投递到 Kafka 中究竟会被哪个 Consumer 读取?这中间的具体逻辑是什么呢?下图给出个非常清晰的解释:(摘抄自 Kafka The Definitive Guide, 2nd Edition ):

image-20240116150556174

下图同理:
在这里插入图片描述

上图中 Consumer Group 中有三个 Consumer 实例,Topic 中有四个分区,Kafka 的安排是:其中两个 Consumer 各自读取一个 Partition,剩下的一个 Consumer 读取其余两个 Partition。所以,你会看到:没有一个 Consumer 能读全所有的消息!大家更像是在分头消化各自的“责任田”。下图是以两个 Consumer Group 为例,再次描述了同样的逻辑:

kafka_consumer_group_scenario_4

下面的两张图依然是描述了这个事实:

在这里插入图片描述
6d9de5f98c922ba6e9cb6a9b592cc529

根据 Consumer Group 的工作特点,我们不难看出:

  1. 一个 Partition 只会被一个 Consumer Group 中的一个 Consumer 实例消费 (不会有同 Group 的两个 Consumer 重复消费一条消息)

  2. 一个 Consumer Group 的 一个 Consumer 实例可能会消费一个 Partition,也可能会消费两个或两个以上的 Partition,还有可能一个 Partition 都不消费,这取决于 Partition 和 Consumer 的数量!以下是我们说的三种可能情形的示意图:

  • Case 1:一个 Consumer Group 只有一个 Consumer,该 Consumer 能读取到全部消息

kafka_consumer_group_scenario_1

  • Case 2:一个 Consumer Group 有多个 Consumer,Consumer 均分 Partition,每个 Consumer 都读取一部分消息

kafka_consumer_group_scenario_2

  • Case 3:一个 Consumer Group 的 Consumer 数量超过了 Partition 的数量,部分 Consumer 因未分配到 Partition,一条消息也不会读到

kafka_consumer_group_scenario_3

Kafka 为什么要设计 Consumer Group 而不是直接以 Consumer 为单位读取 Message?

Kafka 设计 Consumer Group 的意图应该不难揣测,这样做显然是让 Topic 从只能由一个 Consumer 消费变成了:可以多个 Consumer 消费并行消费且还不用担心有重复数据,这样能提升消费端的整体吞吐能力。不过,要注意的是:Kafka 只能保证单个分区内的消息是按产生的先后顺序排列的,在多分区下,无法从整体上保证消息的有序性,所以,当一个 Consumer Group 下有多个 Consumer 一起读取消息时,是不能保证消息的时序性的!

另外由于kafka目前只提供单个分区内的消息顺序,而不会维护全局消息顺序,因此如果用户要实现topic全局消息顺序,就只能通过让每个consumer group下只包含一个consumer实例的方式来间接实现的。

Consumer Group 的相关操作

1. 列出某个 Topics 下的所有 consumer group

kafka-consumer-groups.sh --bootstrap-server $KAFKA_BOOTSTRAP_SERVERS --list

2. 查看某个 Consumer Group 的详细信息

kafka-consumer-groups.sh --bootstrap-server $KAFKA_BOOTSTRAP_SERVERS --describe --group console-consumer-76923

3. 重置偏移量

kafka-consumer-groups.sh --bootstrap-server $KAFKA_BOOTSTRAP_SERVERS --topic 'osci.mysql-server-3.inventory.orders' --group console-consumer-76923 --reset-offsets --to-earliest --execute

小结

最后,我们再简单总结一下:

Kafka中的每一个Consumer都归属于一个特定的Consumer Group,如果不指定,那么所有的Consumer都属于同一个默认的 Consumer Group。Consumer Group 由一个或多个Consumer组成,同一个Consumer Group中的Consumer对同一条消息只消费一次。每个 Consumer Group 都有一个唯一的ID,即Group ID,也称之为 Group Name。Consumer Group 内的所有 Consumer 协调在一起订阅一个Topic的所有Partition,且每个Partition只能由一个 Consumer Group中的一个Consumer进行消费。

参考资料

https://www.luozhiyun.com/archives/260

https://www.conduktor.io/kafka/kafka-consumer-groups-and-consumer-offsets/

https://medium.com/javarevisited/kafka-partitions-and-consumer-groups-in-6-mins-9e0e336c6c00

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值