Consumer Group 是 Kafka 提供的可扩展且具有容错性的消费者机制。

特性

  • Consumer Group 下可以有一个或多个 Consumer 实例。这里的实例可以是一个单独的进程,也可以是同一进程下的线程。在实际场景中,使用进程更为常见一些。
  • Group ID 是一个字符串,在一个 Kafka 集群中,它标识唯一的一个 Consumer Group。
  • Consumer Group 下所有实例订阅的主题的单个分区,只能分配给组内的某个 Consumer 实例消费。这个分区当然也可以被其他的 Group 消费。

消息发送模型

Kafka 仅仅使用 Consumer Group 这一种机制,却同时实现了传统消息引擎系统的两大模型:
如果所有实例都属于同一个 Group,那么它实现的就是消息队列模型(一条消息被group中一个消费者小区);
如果所有实例分别属于不同的 Group,那么它实现的就是发布 / 订阅模型。

位移管理

位移(Offset):消费者在消费的过程中需要记录自己消费了多少数据,即消费位置信息。
其实对于 Consumer Group 而言,它是一组 KV 对,Key 是分区,V 对应 Consumer 消费该分区的最新位移。

老版本vs新版本

老版本的consumer group 将 offset 存储在zk :

  • 减少了 Kafka Broker 端的状态保存开销。
  • 将服务器节点做成无状态的,这样可以自由地扩缩容,实现超强的伸缩性。
  • ZooKeeper 这类元框架其实并不适合进行频繁的写更新,而 Consumer Group 的位移更新却是一个非常频繁的操作。这种大吞吐量的写操作会极大地拖慢 ZooKeeper 集群的性能。

新版本的Consumer Group 将 offset 存储在 kafka 的 topic (_conumser_offsest)中 。

Rebalance

自我理解

为了维护消费者组中消费者与分区的平衡关系,kafka建立了一套再平衡体系来维持这种关系。比如当消费组中由消费者宕机了,就会触发再平衡。将该消费者之前消费的分区按照一定策略分配给其他消费者。来保证消息的及时消费,资源能够得到充分的利用。

概念

Rebalance 本质上是一种协议,规定了一个 Consumer Group 下的所有 Consumer 如何达成一致,来分配订阅 Topic 的每个分区

触发时机

  1. 组成员数发生变更。比如有新的 Consumer 实例加入组或者离开组,抑或是有 Consumer 实例崩溃被“踢出”组。
  2. 订阅主题数发生变更。Consumer Group 可以使用正则表达式的方式订阅主题,比如 consumer.subscribe(Pattern.compile(“t.*c”)) 就表明该 Group 订阅所有以字母 t 开头、字母 c 结尾的主题。在 Consumer Group 的运行过程中,你新创建了一个满足这样条件的主题,那么该 Group 就会发生 Rebalance
  3. 订阅主题的分区数发生变更。Kafka 当前只能允许增加一个主题的分区数。当分区数增加时,就会触发订阅该主题的所有 Group 开启 Rebalance

    分配策略

//todo

问题

在 Rebalance 过程中,所有 Consumer 实例都会停止消费,等待 Rebalance 完成。这是 Rebalance 为人诟病的一个方面。

总结

image.png

问题讨论

你觉得这种消费者组设计的弊端有哪些呢?