kafka-KafkaConsumer.subscribe()和KafkaConsumer.assign()区别

kafka-KafkaConsumer.subscribe()和KafkaConsumer.assign()区别

场景

有两种方式监听kafka消费者消息

  • 指定消费分区
  • 不指定消费分区

不指定消费分区:

@Slf4j
@Component
public class ConsumerListener {

    @KafkaListener(topics = "test", groupId = "test-group")
    public void partition(ConsumerRecord<?, ?> record) {
        handle(record,"consumer-1");
    }

    @KafkaListener(topics = "test", groupId = "test-group")
    public void partition2(ConsumerRecord<?, ?> record) {
        handle(record,"consumer-2");
    }


    private void handle(ConsumerRecord<?, ?> record,String consumerId) {
        final String value = (String) record.value();
        log.info("consumer: {} consume message: {}, partition: {}", consumerId,value, record.partition());
    }
}

指定消费分区:

@Slf4j
@Component
public class SpecialPartitionConsumerListener {


    @KafkaListener(topicPartitions = {@TopicPartition(topic = "test", partitions = {"0"})},
            groupId = "test-group")
    public void partition1(ConsumerRecord<?, ?> record) {
        handle(record);
    }


    @KafkaListener(topicPartitions = {@TopicPartition(topic = "test", partitions = {"1"})},
            groupId = "test-group")
    public void partition2(ConsumerRecord<?, ?> record) {
        handle(record);
    }

    @KafkaListener(topicPartitions = {@TopicPartition(topic = "test", partitions = {"2"})},
            groupId = "test-group")
    public void partition3(ConsumerRecord<?, ?> record) {
        handle(record);
    }

    private void handle(ConsumerRecord<?, ?> record) {
        final String value = (String) record.value();
        log.info("consume message: {}, partition: {}", value, record.partition());
    }

}

问题

在多应用实例的情况下,指定分区消费的方式,会出现重复消费的情况,而没有指定分区消费者就不会。这就很奇怪了,于是就探索一下

在搜索了一番之后,发现是kafka的 subscribe() 和 assign()的区别

  • subscribe: 消费者使用 subscribe() 方法订阅一个或多个主题。在这种模式下,消费者会自动参与消费者组中的平衡机制,即当消费者组中的成员发生变化时(例如消费者加入或离开),Kafka 会重新分配主题分区给消费者组中的消费者。这种模式适用于大多数应用场景,特别是在需要动态平衡分区的情况下
  • assgin: 费者使用 assign() 方法直接分配一组特定的分区。在这种模式下,消费者不会参与消费者组的平衡机制。这意味着一旦你使用 assign() 方法指定了要消费的分区,这些分区就固定了,即使消费者组中的成员发生变化也不会影响这些分区的分配。这种方式通常用于特定的场景,比如需要精确控制哪些分区由哪个消费者消费。在多个应用实例的场景下,同一个分区下,会被不同实例消费,从而出现重复消费方式

如何在指定分区的情况下不会产生重复消费方式呢?

解决方案

使用自定义消费者分区分配策略,确保每个实例只处理一个分区

即在实例启动时,设置实例的Id, 然后用 id对分区数进行取模,取id%partitionNum 为当前实例只能处理的分区数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值