9、消费者组到底是什么?(高扩展性)

文章介绍了Kafka中的消费者组机制,包括其三个特性、消息引擎模型(点对点与发布/订阅)的应用,以及Kafka如何管理位移和触发重平衡的过程。


何谓消费者组(Consumer Group)呢?概括来讲就是:Consumer Group 是 Kafka 提供的可扩展且具有容错性的消费者机制。既然是一个组,那么组内必然可以有多个消费者实例(Consumer Instance),它们共享一个公共的 ID,这个 ID 被称为 Group ID。组内的所有消费者协调在一起来消费订阅主题(Subscribed Topics)的所有分区(Partition)。当然,每个分区只能由同一个消费者组内的一个 Consumer 实例来消费。

1、消费者组的 3 个特性

个人认为,理解 Consumer Group 可以记住下面这三个特性。

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

2、两种消息引擎模型的实现

2.1、点对点模型

点对点模型也称为消费队列,特性是消息一旦被消费,就会从队列中被删除,而且只能被下游的一个 Consumer 消费。

很显然,这种模型的伸缩性(scalability)很差,因为下游的多个 Consumer 都要 “抢” 这个共享消息队列的消息。

2.2、发布/订阅模型

发布/订阅模型倒是允许消息被多个 Consumer 消费,但它的问题也是伸缩性不高,因为每个订阅者都必须要订阅主题的所有分区。(没有消费者组概念的情况下)这种全量订阅的方式既不灵活,也会影响消息的真实投递效果。

2.3、混合模型-消费者组机制

是否有这么一种机制,既可以避开上面这两种模型的缺陷,又兼具它们的优点呢?

Kafka 的 Consumer Group 就是这样的机制。当 Consumer Group 订阅了多个主题后,组内的每个实例不要求一定要订阅主题的所有分区,组内单实例只会消费部分分区中的消息。

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

在了解了 Consumer Group 以及它的设计亮点之后,你可能会有这样的疑问:在实际使用场景中,我怎么知道一个 Group 下该有多少个 Consumer 实例呢?理想情况下,Consumer 实例的数量应该等于该 Group 订阅主题的分区总数。

3、针对 Consumer Group,Kafka 是怎么管理位移的

消费者在消费的过程中需要记录自己消费了多少数据,即消费位置信息。在 Kafka 中,这个位置信息有个专门的术语:位移(Offset)。

看上去该 Offset 就是一个数值而已,其实对于 Consumer Group 而言,它是一组 KV 对,Key 是分区,V 对应 Consumer 消费该分区的最新位移。如果用 Java 来表示的话,你大致可以认为是这样的数据结构,即 Map<TopicPartition, Long>,其中 TopicPartition 表示一个分区,而 Long 表示位移的类型。当然,Kafka 源码中并不是这样简单的数据结构,而是要比这个复杂得多,不过这并不会妨碍我们对 Group 位移的理解。

新版本的 Consumer Group 将位移保存在 Broker 端的内部主题中。

4、重平衡

4.1、什么是重平衡

重平衡是 Consumer Group 端的功能,也就是所谓的 Rebalance 过程。

Rebalance 本质上是一种协议,规定了一个 Consumer Group 下的所有 Consumer 如何达成一致,来分配订阅 Topic 的每个分区。 比如某个 Group 下有 20 个 Consumer 实例,它订阅了一个具有 100 个分区的 Topic。正常情况下,Kafka 平均会为每个 Consumer 分配 5 个分区。这个分配的过程就叫 Rebalance。

4.2、何时重平衡

Consumer Group 何时进行 Rebalance 呢?Rebalance 的触发条件有 3 个。

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

Rebalance 发生时,Group 下所有的 Consumer 实例都会协调在一起共同参与。你可能会问,每个 Consumer 实例怎么知道应该消费订阅主题的哪些分区呢?这就需要分配策略的协助了。

当前 Kafka 默认提供了 3 种分配策略,每种策略都有一定的优势和劣势,我们今天就不展开讨论了,你只需要记住社区会不断地完善这些策略,保证提供最公平的分配策略,即每个 Consumer 实例都能够得到较为平均的分区数。比如一个 Group 内有 10 个 Consumer 实例,要消费 100 个分区,理想的分配策略自然是每个实例平均得到 10 个分区。这就叫公平的分配策略。如果出现了严重的分配倾斜,势必会出现这种情况:有的实例会 “闲死”,而有的实例则会 “忙死”。

### 三级标题:Kafka 消费者机制的工作原理 Kafka消费者(Consumer Group)是一种用于协调多个消费者实例共同消费消息的机制。每个消费者由一个唯一的 `group.id` 标识,并且内的消费者实例共享这一标识。消费者的核心目标是实现负载均衡,确保每条消息在内仅被消费一次,从而避免重复处理。 在同一个消费者中,不同的消费者实例会分配到不同的分区(Partition),以实现并行消费。例如,如果某个主题有三个分区,而消费者中有三个消费者,则每个消费者将各自负责一个分区。如果消费者数量超过分区数,则多余的消费者将处于空闲状态,不会分配到任何分区[^1]。 消费者的另一个关键特性是广播消费能力。当多个消费者订阅了同一个主题时,每个消费者都会独立地接收到该主题的所有消息。这意味着同一消息可以在不同的消费者之间被多次消费,适用于需要多系统同时处理相同数据流的场景[^1]。 消费者中的偏移量管理也非常重要。Kafka 使用内部主题 `__consumer_offsets` 来存储消费者的偏移量信息,确保消费者在重启后能够从上次消费的位置继续读取数据。这种方式比使用 Zookeeper 存储偏移量更适合高并发环境,因为 Zookeeper 在频繁写入时性能较差[^4]。 消费者的动态平衡(Rebalance)机制也是其核心功能之一。当消费者内的成员发生变化(如新增消费者或某个消费者宕机)时,Kafka 会触发一次再平衡操作,重新分配分区给当前活跃的消费者。这一过程由 Kafka 的协调器(Coordinator)负责管理,并通过心跳机制检测消费者是否存活。 为了确保消费者的高效运行,配置参数的选择至关重要。例如,`bootstrap.servers` 应与生产者保持一致,以便正确连接 Kafka 集群;`group.id` 必须具有业务含义,便于后续维护和监控;`client.id` 可选,但建议设置,以帮助识别具体的消费者实例[^3]。 以下是一个典型的 Kafka 消费者配置示例: ```java public static Properties initConfig() { Properties props = new Properties(); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "my-consumer-group"); props.put("client.id", "consumer.client.id.demo"); return props; } ``` 消费者机制的设计使得 Kafka 能够在大规模数据流处理中实现高效的水平扩展和容错能力。它不仅支持高吞吐量的消息消费,还能根据系统负载动态调整资源分配,确保系统的稳定性和可靠性。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值