Kafka 的 Share Group 是什么?Kafka 也能当队列用了吗?

第 1098 题 约 2 分钟读完

本文目录
  1. 面试怎么回答
  2. 传统消费组的限制
  3. Share Group 怎么做
  4. 代价:没有顺序保证

面试怎么回答

普通消费组里一个分区同时只能给一个消费者,并发度被分区数卡死,offset 又只能整体前进,一条慢消息会堵住整个分区。Kafka 4.0 起引入的 Share Group 提供了队列语义:多个消费者可以协同消费同一个分区,Broker 给领取的消息加带超时的锁,消费者对每条消息单独确认接受、释放或拒绝,超时未确认会重新投递,还有投递次数上限防止毒消息。代价是不保证顺序,所以按 key 有序的 CDC、订单流继续用普通消费组,每条消息独立、需要弹性扩并发的任务分发用 Share Group。它比较新,上生产前要确认版本成熟度和客户端支持。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

Kafka 4.0 开始引入 Share Group(KIP-932,社区叫它「Queues for Kafka」),后续版本逐步完善。面试官问这个,是想看你清不清楚 Kafka 传统消费组的限制,以及「队列语义」和「流语义」的区别。

传统消费组的限制

在普通的 Consumer Group 里,一个分区同一时间只能被组内一个消费者消费,消费进度用一个 offset 表示。这带来两个问题:

  • 并发度被分区数卡死:Topic 有 12 个分区,组里最多 12 个消费者干活,再加机器也是空闲。临时任务高峰想扩到 100 个消费者,只能先加分区,而分区加了就减不回来。
  • 一条慢消息堵住整个分区:offset 只能整体往前推,某条消息处理慢或者失败,后面的消息都得等着。

对于「每条消息是一个独立任务、谁处理都行、不要求顺序」的场景(比如发通知、跑异步任务),这种模型并不合适,大家以前只能去用 RabbitMQ、RocketMQ 这类队列。

Share Group 怎么做

Share Group 让多个消费者可以协同消费同一个分区,按「单条消息」来管理状态:

  1. 消费者拉取消息时,Broker 把这批消息标记为「已被某个消费者领取」,并加一个领取锁,锁有超时时间;
  2. 消费者处理完对每条消息单独确认:接受(处理成功)、释放(放回去让别人再处理)、拒绝(不再投递);
  3. 锁超时还没确认的消息会被重新投递给别的消费者;
  4. 每条消息有投递次数上限,超过上限就不再投递,避免毒消息无限重试。

这样消费者数量可以超过分区数,慢消息也不会卡住其他消息。

代价:没有顺序保证

Share Group 不保证顺序,同一个分区的消息会被多个消费者并行处理。所以:

  • 需要按 key 有序的场景(同一订单的状态变更、CDC 数据)继续用普通消费组;
  • 每条消息独立、追求弹性并发的任务分发场景,适合 Share Group;
  • 它属于较新的功能,上生产前要确认你所用 Kafka 版本里它的成熟度,以及客户端是否支持。