消费者和消费者群组
Kafka 消费者从属于消费者群组。一个群组里的消费者订阅的是同一个主题,每个消费者 接收主题一部分分区的消息。
假设主题 T1 有 4 个分区,我们创建了消费者 C1,它是群组 G1 里唯一的消费者,我们用 它订阅主题 T1。消费者 C1 将收到主题 T1 全部 4 个分区的消息,如图 4-1 所示
如果在群组 G1 里新增一个消费者 C2,那么每个消费者将分别从两个分区接收消息。我们 假设消费者 C1 接收分区 0 和分区 2 的消息,消费者 C2 接收分区 1 和分区 3 的消息,如图 4-2 所示。
如果群组 G1 有 4 个消费者,那么每个消费者可以分配到一个分区,如图 4-3 所示。
如果我们往群组里添加更多的消费者,超过主题的分区数量,那么有一部分消费者就会被 闲置,不会接收到任何消息,如图 4-4 所示。
往群组里增加消费者是横向伸缩消费能力的主要方式。
不要让消费者的数 量超过主题分区的数量,多余的消费者只会被闲置。一个分区只能由同一个消费组内一个消费者消费。
除了通过增加消费者来横向伸缩单个应用程序外,还经常出现多个应用程序从同一个主题 读取数据的情况。
在上面的例子里,如果新增一个只包含一个消费者的群组 G2,那么这个消费者将从主题 T1 上接收所有的消息,与群组 G1 之间互不影响。群组 G2 可以增加更多的消费者,每个 消费者可以消费若干个分区,就像群组 G1 那样,如图 4-5 所示。总的来说,群组 G2 还是 会接收到所有消息,不管有没有其他群组存在。
消费者群组和分区再均衡
分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为再均衡。
在再均衡期间,消费者无法读取消 息,造成整个群组一小段时间的不可用。
它有可能还需要去刷新缓存,在它重新恢复状态之前会拖慢 应用程序。
消费者通过向被指派为群组协调器的 broker(不同的群组可以有不同的协调器)发送心跳 来维持它们和群组的从属关系以及它们对分区的所有权关系。
消费者会在轮询消息 (为了获取消息)或提交偏移量时发送心跳。如果消费者停止发送心跳的时间足够长,会 话就会过期,群组协调器认为它已经死亡,就会触发一次再均衡。
分配分区是怎样的一个过程
当消费者要加入群组时,它会向群组协调器发送一个 JoinGroup 请求。第一 个加入群组的消费者将成为“群主”。群主从协调器那里获得群组的成员列 表(列表中包含了所有最近发送过心跳的消费者,它们被认为是活跃的), 并负责给每一个消费者分配分区。它使用一个实现了 PartitionAssignor 接 口的类来决定哪些分区应该被分配给哪个消费者。 Kafka 内置了两种分配策略,在后面的配置参数小节我们将深入讨论。分配 完毕之后,群主把分配情况列表发送给群组协调器,协调器再把这些信息发 送给所有消费者。每个消费者只能看到自己的分配信息,只有群主知道群组 里所有消费者的分配信息。这个过程会在每次再均衡时重复发生。
提交和偏移量
每次调用 poll() 方法,它总是返回由生产者写入 Kafka 但还没有被消费者读取过的记录, 我们因此可以追踪到哪些记录是被群组里的哪个消费者读取的。