kafka自动提交方式下的重复消费解决办法

最近项目上遇到一个kafka重复消费的问题,大体描述一下:

程序日志显示一直在重复消费从kafka中获取到的其中500条记录,处理这500条数据耗时8分钟。kafka的server.log日志一直在提示rebalance。

网上找了很多帖子,发现其中对于max.poll.records和session.timeout.ms两者关系的描述基本都是错误的,错误描述如下:

# max.poll.records条数据需要在session.timeout.ms这个时间内处理完,默认:500

# 即 max.poll.records * (处理能力)  <= session.timeout.ms 可正常消费,不满足会出现rebalance

spring.kafka.consumer.max-poll-records=500

ok,口说无凭,实操一下:

配置如下:

spring.kafka.consumer.max-poll-records=20

spring.kafka.consumer.properties.session.timeout.ms=10000

处理程序每次用Thread.sleep(1000)来模拟,即程序的处理能力为1秒消费一条记录,安装上述配置,20条记录至少需要20秒,配置10秒显然不够,肯定会出现rebalance。

实测结果,正常处理,kafka也没有出现rebalance。

why? 显然,max.poll.records和session.timeout.ms两者的关系不是如此,继续深入一下。

我们再来看看上面的session.timeout.ms,指的是什么,为了准确,直接去官网:

 

翻译一下,基本就是说:

session.timeout.ms为会话的超时限制。如果consumer在这段时间内没有发送心跳信息,则它会被认为挂掉了,并且reblance将会产生,必须在[group.min.session.timeout.ms, group.max.session.timeout.ms]范围内。默认:10000。

显然并没有提到与max.poll.records的关系。

 

查阅官网,发现一个属性max.poll.interval.ms,官网描述如下:

 

基本意思就是消费者两次调用poll()取数据的最大延迟时间,超过这个时间消费组会发生rebalance。

消费者第一次poll到数据后,会开始消费,直到本次数据处理完毕,才会进行下一次poll,也就是说:

max.poll.records * (处理能力)  <= max.poll.interval.ms,程序即可正常消费。

实操一下,现象确实如此,这里就不附带结果了。

写这篇帖子,主要是因为鄙人踩了这个坑,希望其它人不要继续了,哈哈。

从上面公式可以看到,我们只要保证程序处理能力稳定,不会随着时间或者数据量增大,那这rebalacnce就不会出现了。

可以采用异步消费的方式。
————————————————

原文链接:https://blog.csdn.net/u011801264/article/details/103921462

posted @ 2021-03-10 15:33  八方鱼  阅读(2544)  评论(0)    收藏  举报