Kafka消息丢失
原因分析
-
Producer的ACK机制
等级设置0或者1,可能因为没落盘或者没同步Follower导致丢失
Producer发送消息到队列,分区Leader收到消息后返回ACK给Producer,表示接收成功,此时可以继续发送下一笔消息。
Kafka提供了3种不同级别的ACK机制
0:Leader收到消息后立刻返回给Producer,消息可能还没刷盘,也还没有同步给Follower。此时如果Leader挂掉,消息就丢失了。
1:Leader将消息写入磁盘后,立刻返回ACK给Producer,消息可能还没同步Follower。此时如果Leader挂掉,选举新的Follower成为主分区,因为刚才没同步成功,所以消息丢失。
-1:Leader将消息写入磁盘,并且同步给所有Follower,此时再返回ACK。这个方案也存在一个问题,如果在Leader准备返回ACK的时候挂掉,Producer没收到ACK认定为发送失败。此时又有2种情况
(1)开启重试:会导致队列收到2条重复的消息,此时**需要Consumer端保证消费幂等**,后面会介绍; (2)不开启重试(不推荐):网络问题、超时等原因导致发送失败,不会重新发送,**消息容易丢失**。
-
Consumer设置自动提交
消费失败来不及记录异常就宕机,但是Offset提交了,导致丢失
Consumer进行消费时,提交Offset偏移给Kafka记录消费的最新位置。 提交Offset有以下2种方式:
自动提交:enable.auto.commit 设置 true 开启,auto.commit.interval.ms 设置自动提交的频率间隔。Consumer获取到消息就提交Offset,不管消费是否成功
手动提交:enable.auto.commit 设置 false ,消费完成后再调用 consumer.commit(),手动更新Offset。如果消费失败,我们可以将异常记录进行人工干预,然后再提交Offset,避免影响后面消息的消费。
解决方案
-
ACK参数设置为-1
对性能要求不是极高的情况下,建议将ACK设置-1,我们只需要在 Consumer 端结合幂等性避免消息重复消费。
Kafka消息重复消费
背景描述
-
内容介绍
发现每条消息处理时间长达30+秒,消息处理完后,又重新从第一条开始重复消费。
原因分析
-
Kafka异常重启
kafka每个消息写进去,都有一个offset,代表他的序号。consumer消费数据之后,每隔一段时间,会把自己消费过的消息的offset提交一下提交到zookeeper,代表我已经消费过了。
下次要是重启,而offset未及时提交,则会从上次消费到的offset来继续消费。
-
Kafka消息消费设置时长小于实际业务执行时长
Kafka消费者有两个配置参数:
max.poll.interval.ms
两次poll(拉取)操作允许的最大时间间隔。单位毫秒。默认值300000(5分钟)。
两次poll超过此时间间隔,Kafka服务端会进行rebalance操作,导致客户端连接失效,无法提交offset信息,从而引发重复消费。
max.poll.records
一次poll操作获取的消息数量。默认值50。
如果每条消息处理时间超过60秒,那么一批消息处理时间将超过5分钟,从而引发poll超时,最终导致重复消费。
解决方案
-
幂等性处理
可以参照博主写的这篇文章:Java并发编程学习之高并发下如何保证接口的幂等性
-
参数优化
-
分析业务代码逻辑,进行性能优化,确保每条消息处理时间控制在合理范围
每条消息的处理时间不要超过5分钟。如果超过5分钟,则考虑进行架构上的优化。
比如A线程消费消息,放到进程内部队列中,提交offset;其他线程从内部队列取消息,并处理业务逻辑。为防止内部队列消息积压,A线程需要监控队列中消息数量,超过一定量时进入等待。
-
适当增大max.poll.interval.ms的值
SpringBoot没有提供可调节此数值的参数。如果修改此数值,需要自己封装方法创建Kafka客户端:
org.apache.kafka.clients.consumer.KafkaConsumer.KafkaConsumer<String,String>(Properties)
-
适当减小max.poll.records的值
可通过SpringBoot配置参数"spring.kafka.consumer.max-poll-records"调整。
spring: kafka: consumer: max-poll-records: 500 properties: max: poll: interval: ms: 500000
-
参考链接
-
解决Kafka重复消费问题
https://blog.youkuaiyun.com/xianyuxiaoqiang/article/details/86477976
-
Kafka配置max.poll.interval.ms参数
https://blog.youkuaiyun.com/yuanpanni/article/details/107388269
-
Kafka消息丢失、重复消费的解决方案
https://blog.youkuaiyun.com/qq_28834355/article/details/113663832
-
Kafka(一)Kafka的简介与架构
https://www.cnblogs.com/frankdeng/p/9310684.html