消费组
消费组是 Kafka 的消费模型核心:组内分区分摊、组间广播。面试主线:分配机制、offset 管理、再平衡。
消费模型
组内分摊: 分区是分配单位
- 一个分区同一时刻只能被组内一个消费者消费
- 组内消费者数 > 分区数:多余消费者空闲(白挂)
- 不同消费组:各消费各的(广播语义)
分区分配策略
| 策略 | 机制 | 特点 |
|---|---|---|
| Range | 按分区范围切 | 分配不均(topic 多时) |
| RoundRobin | 轮流分配 | 均匀 |
| Sticky | 尽量保持上次分配 | 再平衡影响最小(Kafka 3.x 起默认 CooperativeSticky) |
offset 提交
- offset = 消费位置:消费者读到的分区序号,提交后记录
- 提交时机决定语义:
| 模式 | 时机 | 语义 |
|---|---|---|
| 自动提交(enable.auto.commit) | 周期提交(默认 5s) | 可能重复消费(提交前崩溃) |
| 手动同步提交 | 处理完提交 | 简单可靠 |
| 手动异步提交 | 处理完异步提交 | 性能好,回调处理失败 |
- 先处理再提交:消息不丢(at-least-once);代价是可能重复(见重试与幂等篇)
- 消费端幂等是标配(重复消费必然存在)
再平衡(Rebalance)
触发:消费者加入/退出/崩溃、分区数变化。
| 阶段 | 说明 |
|---|---|
| 发现问题 | 心跳超时(session.timeout) |
| 协调 | GroupCoordinator 触发 rebalance |
| 重新分配 | 按策略重分分区 |
| 停止消费 | 再平衡期间整个组暂停消费 |
优化:
- 缩短检测(session.timeout 调小,但别太敏感误判)
- Sticky 策略减少重新分配范围
- 消费端处理要快(rebalance 前处理完,max.poll.interval)
面试追问
- 分区怎么分配? 分区是分配单位:一个分区同一时刻归组内一个消费者。消费者多于分区会空闲
- offset 提交时机? 处理完再提交(at-least-once)。自动提交可能重复消费
- 重复消费怎么办? 消费端幂等(唯一键)。先处理后提交的代价就是可能重复
- 再平衡是什么? 成员变化触发重新分配,期间整组暂停。Sticky 策略减少影响
- 消费组扩容上限? 分区数:消费者不能超过分区数。扩容前先加分区