消费者客户端使用kafkaconsumer向broker订阅topic,接收消息进行消费。kafka中消息的消费,要知晓两个紧密相关的概念:消费者consumer和消费者组consumer group。

消费者和消费者组

每个consumer的实例只属于某一个consumer group。

对于每个consumer group,在任意时刻,每个分区partition至多有一个consume实例在消费,反过来,consumer group中的每个consumer独占一个或多个partition分区。

举例来说,4个分区,当前consumer group组内只有三个consumer实例,那么其中会有一个consumer实例消费两个分区的消息。

如果同一个主题topic需要被多个应用消费,那么,只需要为每个应用创建各自的consumer group,这样每个应用也就是每个consumer group能够消费该主题topic的所有消息。

每个consumer group可以订阅多个主题topic,比如consumer group订阅了三个主题topic,每个主题分别有1,2,3个分区,那么可以设定consumer group下有6个消费者实例,这样每个消费者实例就对应消费这三个主题下的一个分区。

消费者组重平衡

每个consumer group都有一个协调者coordinator来负责分配消费者consumer和分区partition的关系。当consumer实例或者partition发生了变更,会触发reblance过程,重新分配消费者consumer和分区partition的关系。

1. 组成员的数量发生了变化,也就是consumer增加或者减少了

2. 订阅的主题的分区数发生了变化,比如该主题topic又新增或者减少了分区

3. 订阅主题的数量发生了变化,比如由原来订阅的1个主题topic下有3个分区,又新增订阅了另外一个有4个分区的主题topic,其实这也相当于是2中的分区数量发生了变化。

组成员的数量发生了变化是最常见的,举个最简单的例子,当消费者应用在发布或者重启的过程中,就可能会触发rebalance的过程。

消费者实例通过心跳来与协调者coordinator通信,一旦某个消费者实例一段时间没有发送心跳请求给协调者,协调者就会认为这个消费者实例挂了,就会决定开启一轮新的重平衡。

那么问题来了,协调者是如何通知其他消费者实例来进行重平衡的?

其实很简单,其他消费者实例也是在和协调者不停的发送心跳请求的,一旦协调者决定开启新的一轮重平衡,那么就会将相关的通知信息封装到心跳请求的响应中,这样其他消费者实例就会感知到这个重平衡的通知。