Kafka集群消费和广播消费的实现

Kafka消费模型

同一个消费组者的多个消费者实例会分别消费同一个topic下不同分区的数据,在消费者充足的条件下,每个分区最多也只有一个消费者实例;当消费者数量少于分区数量时,某个消费者会同时对应多个分区。

所以当某个topic下消息量激增时,如果只增加消费者实例数量可能并不能达到较好的效果,因为多余分区数的消费实例是空闲的,因此需要同时扩容分区数和消费者实例数量才能达到较好的效果

集群消费

默认情况下Kafka中同一个topic下的消息对于某一个消费组来说是集群消费模式,也就是只会被组内一个消费实例所消费。

广播消费

同一个topic下的消息被多个消费者消费称为广播消费.由于Kafka默认是集群消费模式,所以广播消费的实现方式就是为广播消费的多个应用实例都设置不同的GroupId即每个实例都是单独的消费组.

@KafkaListener注解的GroupId属性支持SpEL表达式,可以通过这个实现每个应用实例都是单独的消费组,进而实现广播消费。

下面表达式指的是取值java.util.UUID这个类的randomUUID方法,当然也可以通过后缀当前机器ip的方式实现动态groupId

1
2
@KafkaListener(topics = {"topic"}, properties = {"auto.offset.reset=latest"},
          groupId = "consumerGroup-" + "#{T(java.util.UUID).randomUUID()}")

避坑指南

由于是通过动态设置GroupId的方式来实现广播消费,所以当服务重启时GroupId就会改变,消费组改变会导致原先的消费进度丢失,因此需要正确配置 auto.offset.reset 参数。配置为 earliest 会有重复消费的可能,需要实现消费逻辑幂等。配置为 latest 会有漏消费的可能,开发中需要结合实际业务场景进行配置和实现程序幂等。