Kafka未确认消息重投递时机及同组多消费者行为咨询
Kafka 消费者未提交偏移量的消息重投及消费组内投递问题
问题背景
配置如下:
enable.auto.commit=false max.poll.records=1 auto.offset.reset=latest group.id="processor-1"
代码实现:
KafkaConsumer<String,String> consumer= new KafkaConsumer<String,String>(properties); consumer.subscribe(Arrays.asList(topic)); while(true) { ConsumerRecords<String,String> records=consumer.poll(Duration.ofSeconds(1)); for(ConsumerRecord<String,String> record: records){ logger.info("Value:" +record.value()); logger.info("Partition:" + record.partition()+",Offset:"+record.offset()); //consumer.commitSync(); } }
已知自动提交关闭且未手动确认消息,需解答以下问题:
- 该消息会在多久后被重新投递?
- 同一消费组内存在多个消费者时,消息'A'被consumer-1读取但未确认,何时会被投递到consumer-2?
问题解答
1. 未提交偏移量的消息重投时机
Kafka本身不会主动触发未提交消息的重投,只有当消费者发生重平衡(Rebalance)或者消费者重启时,才会重新分配分区。此时负责该分区的新消费者(或重启后的原消费者)会从该分区最后一次提交的偏移量位置开始拉取消息,这就相当于未提交的消息被重新处理。
如果消费者一直正常运行且未触发重平衡,哪怕始终不提交偏移量,Kafka也不会重复投递这条消息——因为当前消费者持有该分区的所有权,只要它持续调用poll(),就会继续拉取下一条消息,不会回头处理未提交的旧消息。
2. 同一消费组内消息转移到其他消费者的时机
只有当consumer-1失去对应分区的所有权时,消息'A'所在的分区才会被分配给consumer-2,此时consumer-2会从该分区最后一次提交的偏移量开始拉取,进而处理包括'A'在内的未提交消息。
触发consumer-1失去分区所有权的场景包括:
- consumer-1崩溃或主动退出
- consumer-1长时间未调用
poll(),超过session.timeout.ms(默认30秒)或max.poll.interval.ms(默认5分钟),被组协调器判定为“死亡”,触发重平衡 - 消费组内新增/移除消费者,触发重平衡
内容的提问来源于stack exchange,提问作者Siddhartha Sadhukhan
相关产品推荐
相关产品推荐

