1. 消费组核心概念
各位同学,咱们今天聊聊 Kafka 里最核心的一个概念——Consumer Group。说实话,我刚开始接触 Kafka 时,对消费组的理解也走了不少弯路。记得有一次线上事故,就是因为消费组配置不当,导致消息重复消费,业务方半夜打电话找我……嗯,从那以后,我对消费组就格外上心。
1.1 什么是 Consumer Group
Consumer Group,说白了就是一组消费者的逻辑集合。它们共同消费一个或多个 Topic 的消息,并且每个分区只能被组内的一个消费者消费。
你想想看,如果没有消费组,每个消费者都得自己记录消费位置,管理起来多麻烦。有了消费组,Kafka 帮我们做了三件重要的事:
- 负载均衡:分区自动分配给组内消费者
- 故障转移:某个消费者挂了,分区自动重新分配
- 消费进度管理:偏移量由 Group Coordinator 统一管理
核心要点:同一个消费组内的消费者,它们的 group.id 必须相同。这是 Kafka 识别消费组的唯一标识。
我在项目中遇到过一种情况:开发同学把不同业务的消费者配成了同一个 group.id,结果两个服务互相抢分区,消息处理全乱套了。所以,group.id 的命名一定要规范,我习惯用「业务线_模块_用途」的格式,比如 order_payment_processor。
1.2 消费组与分区的关系
这部分是面试高频题,也是实际开发中容易踩坑的地方。咱们先看一张图,把关系理清楚:
从图上可以看得很清楚:4 个分区分配给 3 个消费者。这里有个关键规则——一个分区只能被同一个消费组内的一个消费者消费。但反过来,一个消费者可以消费多个分区。
为什么会这样设计?我个人的理解是:Kafka 要保证分区内的消息顺序。如果多个消费者同时消费同一个分区,顺序就乱了。这是 Kafka 在「顺序性」和「并行度」之间做的权衡。
经验之谈:消费组内的消费者数量不要超过分区数。多出来的消费者会闲置,白白浪费资源。我一般建议消费者数量等于分区数,或者略少。
咱们用表格总结一下分区分配的核心规则:
| 场景 | 分配结果 | 说明 |
|---|---|---|
| 消费者数 = 分区数 | 1:1 分配 | 最理想的情况,每个消费者处理一个分区 |
| 消费者数 < 分区数 | 部分消费者处理多个分区 | 常见场景,注意单个消费者的负载 |
| 消费者数 > 分区数 | 部分消费者闲置 | 浪费资源,尽量避免 |
1.3 消费组的状态机模型
这部分是理解消费组「灵魂」的关键。Kafka 的消费组是有生命周期的,它会在不同状态之间转换。我当年排查一个消费组卡住的问题时,就是靠状态机模型定位到问题的。
消费组有 5 种状态:
- Empty:组内没有消费者,这是初始状态
- PreparingRebalance:准备重新分配分区
- CompletingRebalance:正在完成重新分配
- Stable:稳定运行中,一切正常
- Dead:组已失效,无法再使用
咱们看一张状态转换图:
状态转换的核心触发点是 再平衡(Rebalance)。什么时候会触发再平衡?我总结了几种常见情况:
- 消费者加入:新消费者启动,加入消费组
- 消费者退出:消费者主动关闭或超时未发送心跳
- 分区变化:Topic 的分区数发生变化
- 订阅变化:消费者订阅的 Topic 发生变化
注意:再平衡期间,所有消费者都会暂停消费。如果业务对实时性要求高,再平衡的「停顿时间」就是你需要重点关注的指标。我曾经遇到过一个消费组,每次再平衡要 30 秒,业务方直接投诉。
我个人习惯在生产环境中监控两个关键指标:
- 再平衡频率:正常情况下,几分钟一次就算频繁了
- 再平衡耗时:超过 10 秒就需要排查原因