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

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

  • 1、消费者组的 3 个特性
  • 2、两种消息引擎模型的实现
    • 2.1、点对点模型
    • 2.2、发布/订阅模型
    • 2.3、混合模型-消费者组机制
  • 3、针对 Consumer Group,Kafka 是怎么管理位移的
  • 4、重平衡
    • 4.1、什么是重平衡
    • 4.2、何时重平衡

何谓消费者组(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 表示位移的类型。当然,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,分布式,分区)