消息队列-kafka提交offset问题

说明:转载本人掘金文章

概述

offset是相对Consumer来说的,offset是用来帮助记录某个主题某个分区的消费情况的。当你每提交一次offset,意味着向kafka汇报一次消费进度,对于提交offset所以又分为同步和异步提交

同步和异步提交offset对比

同步提交:

1.每次处理完一条消息,然后调用consumer.commitSync()提交offset

2.在调用consumer.commitSync()方法时候会堵塞住,严重影响消费者性能

3.每次提交都会向__consumer_offsets发送一条消息,增加__consumer_offsets提交频率,影响kafka性能

4.同步提交好处在于不会出现重复消费的情况,处理每条都及时被kafka记录下来

异步提交:

1.每次提交了(commitAysnc())一些offset之后,会提交最后一个offset最大的

2.在调用commitAysnc()不会阻塞消费者,一定程度提高了消费者处理消息性能

3.每隔一批消息,真正汇报一次offset到kafka,但是如果中间发生异常,提交offset失败将导致重复消息

案例

同步提交:

//配置
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.listener.ack-mode=manual_immediate //立刻提交

//每次调用ack.acknowledge()会提交,会提交一次offset
 @KafkaHandler
    @KafkaListener(topics = "quickstart-events",groupId = "test-consumer-group-4",concurrency = "1")
    public void test11(ConsumerRecord record, Acknowledgment ack){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("接收消息:"+String.format(
                "(消息体)%s--(分区)%s--(消费者实例)%s",record.value(),record.partition(),Thread.currentThread().getName()));
        ack.acknowledge();
    }

投入10条消息

image.png

消费前__consumer_offsets的48分区情况

image.png

消费后__consumer_offsets的48分区情况

image.png

说明:可以看到__consumer_offsets的48分区多了11(多的一条我们先不讨论)条消息

异步提交:

//配置
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.listener.ack-mode=manual   //不是马上提交,而是按照异步批次提交一次

//增加max.poll.records=4参数,意味者一批4条消息,10条消息应该提交三次offset
@KafkaHandler
    @KafkaListener(topics = "quickstart-events",properties = {"max.poll.records=4"},groupId = "test-consumer-group-4",concurrency = "1")
    public void test11(ConsumerRecord record, Acknowledgment ack){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("接收消息:"+String.format(
                "(消息体)%s--(分区)%s--(消费者实例)%s",record.value(),record.partition(),Thread.currentThread().getName()));
        ack.acknowledge();
    }

投入10条消息

image.png

消费前__consumer_offsets的48分区情况

image.png

消费后__consumer_offsets的48分区情况

image.png
说明:可以看到__consumer_offsets的48分区多了4(多的一条我们先不讨论)条消息

总结

可以看到异步提交不仅可以提高消费端性能,同时__consumer_offsets的压力也会降低,其实按照批次异步提交方案是最佳选择,只要我们做好消费端幂等性即可

你可能感兴趣的:(消息队列,kafka,java,分布式)