spring-kafka消费数据 重复消费问题(针对提交offset偏移产生重复消费的问题)

spring-kafka 重复消费数据

spring集成kafuka框架

最近公司需要对接kafka拉取数据,在使用spring-kafka框架时候,总是无法持续消费,总是出现持续消费,相当纠结。因为也是刚接手任务,故整理了一下遇到的难题,特此整理一下,望对各位同学有些帮助。

版本介绍

项目架构主要是spring mvc 架构版本是5.0.2.RELEASE版本,spring-kafka版本是2.1.0.RELEASE ,kafka-client的版本是1.0.0版本。

在消费数据的时,遇见如下异常错误信息:

提交offset时kafka出现的异常
理解下来就是当kafka处理完500记录后去提交offset偏移量的时候,发现会话已经结束了,认为系统处理完成了,需要重新分配分区,在分区的时候出现了混乱,导致系统又要重新去消费已消费过的数据。重复消费数据。
MAX_POLL_INTERVAL_MS_CONFIG属性意思为kafka消费者在每一轮poll()调用之间的最大延迟,消费者在获取更多记录之前可以空闲的时间量的上限。这个参数不能跟 SESSION_TIMEOUT_MS_CONFIG时间数相同 需要比SESSION_TIMEOUT_MS_CONFIG时间要大些。

解决方案

随后根据业务处理的复杂程度以及耗时的长短做出了参数调整,

主要是配置consumerConfig对象,截图如下:
consumerConfigs对象配置

主要注意的是需要将ENABLE_AUTO_COMMIT_CONFIG 提交改为false,借此转交给spring-kafka框架帮忙提交
offset偏移量,同时需要将SESSION_TIMEOUT_MS_CONFIG时间长度根据设置MAX_POLL_RECORDS_CONFIG的记录数来计算一个会话时长。最后进行平衡调整。

目前生产者传入2个队列,每个队列有5个分区,实时去推送数据。而对应消费者需要创建5个及以上的副本去消费数据。

目前只是针对一个topic队列做了副本增量。后续会对另一个topic队列做副本增量。

在经历了几点的数据跑试之后,目前发现录入数据库的效率非常缓慢,平均处理一条订单数据耗时在3s左右,实在不能忍受了,最后直接换了一个新库数据专门录入此库,效率非常明显了,房单数据堆积量已为0达到了实时同步,订单数据堆积量已剩下40万左右,可以在一天左右可以将堆积量消耗为0 。 讲这些的意思,这次的问题出现应该属于数据库达到瓶颈。需要从数据库吞吐量考虑程序效率问题。

Spring Kafka中的手动提交是指在消费者应用程序中显式地将消费的位置信息(offset)发送回Kafka服务器,以更新消费者的偏移量记录。这通常发生在以下几种情况: 1. **批量处理完成**:如果你的应用需要对接收到的消息进行批处理,处理完成后,你需要确认这一批次已经成功处理,这时可以手动提交对应的offset。 2. **异常恢复**:如果因为某个错误导致消息无法正常处理,消费者可以选择重新开始从最近一次提交的位置读取,而不是从头开始,这就需要用到手动提交。 3. **幂等性和一致性保证**:某些场景下,消费者需要确保处理消息的结果是幂等的,手动提交能帮助跟踪每个消息的处理状态。 在Spring Kafka中,手动提交通常是通过`org.springframework.kafka.annotation.KafkaListener`的`@CommitPolicy`注解设置为`COMMIT_ON_SUCCESS`或使用`KafkaTemplate`的`sendAndForget()`方法配合`commitOffset()`方法来实现的。例如: ```java @Bean public ConcurrentKafkaListenerContainerFactory<String, String> containerFactory() { ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory()); // 设置手动提交策略 factory.setCommitOnCompletion(true); return factory; } // 或者在监听器方法中手动提交 @Autowired private MessageListenerContainer messageListenerContainer; @KafkaListener(topics = "my-topic") public void listen(@Payload String message) { try { // ...业务处理... messageListenerContainer.commitMessage(message, true); // 手动提交 } catch (Exception e) { // 异常处理... } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值