Expiring 1 record(s) for 2:xxx ms has passed since batch问题研究

本文探讨了Kafka生产者遇到的TimeoutException,主要原因是请求超时、批次大小配置及网络问题。解决方案包括调整request.timeout.ms、batch.size配置,以及检查磁盘空间。若目标分区为负数也可能导致此问题,建议指定分区或使用ProducerInterceptor重写分区逻辑。注意这些操作可能影响消费者行为。

本文主要对该错误相关文章进行整理,供自己以及各位参考,如有问题请及时指出,谢谢。

报错大意为:生产发送批次已经创建,但是已经过去120000ms,仍然没有发送,消息过期。

【20211015更新】(@高警,感谢提供资料)
当kafka服务器磁盘空间不足时,也会报此错误。清空磁盘空间,重启kafka服务即可解决。

主要原因有两类

  1. https://stackoverflow.com/questions/46649748/kafka-producer-timeoutexception-expiring-1-records

    共有3个可能解决方案

    1. 增大 request.timeout.ms 配置
      这个配置指的是 kafka 等待发送批次大小(以字节为单位)的等待时间,如果超过该时间未满足批次大小,将会超时。
    2. 减少 batch-size 配置
      结合上面原因,降低批次条数,少量多发,减少等待时间。
    3. 网络原因,无法满足高负载

    但是也有人提出疑问:
    ling.ms 默认值时0,即使批次大小没有达到,也会立即发送的。
    即使为了减少频繁发送的情况,假设设置为20ms(小于过期时间120000ms),那么过了这20ms,尽管批次大小没有到,生产者也会发送该批次的,是不会出现超时情况的。

  2. https://stackoverflow.com/questions/56807188/how-to-fix-kafka-common-errors-timeoutexception-expiring-1-records-xxx-ms-has

    该问题提出者,指出 对batch.size linger.ms request.time.out 都进行配置,但是依旧会报错。
    仔细查看日志发现,发送消息时,目标topic的目标分区,是负数。
    但是在该问题下,未发现更加合理的解决方案以及出现负数的原因,但是,大概率是因为这个问题导致的如标题的报错。

  3. 个人想法(临时解决该问题)

    1. 发送消息时,指定某个分区
    2. 通过ProducerInterceptor重写分区逻辑
      但是 要注意 分区逻辑对消费者消费数据是否有影响。
Kafka消费者组中出现“expiring 40 records because 120097 ms has passed since batch creation”这一现象,通常与消费者处理消息的效率和配置参数密切相关。Kafka消费者在拉取消息后,会将这些消息缓存在本地,并在一定时间内进行处理和提交。如果处理时间过长,超过了设定的超时时间,则会导致消息批次过期。 ### 消息批次过期的原因 Kafka消费者在调用`poll()`方法时,会从Broker拉取一批消息到本地缓存中。这批消息的处理时间从拉取完成开始计算。如果消费者在处理这批消息时,耗时超过`max.poll.interval.ms`(默认为300000毫秒,即5分钟),则Kafka会认为该消费者已经无法正常处理消息,从而触发消费者组的再平衡(Rebalance)。此时,消费者尚未处理完的消息会被标记为“expiring”,并最终被丢弃[^4]。 ### 配置建议 1. **调整`max.poll.interval.ms`** 如果消费者的处理逻辑较为复杂,导致单次处理耗时较长,可以适当增加`max.poll.interval.ms`的值。这样可以延长消费者在不触发再平衡的情况下处理消息的时间窗口。例如: ```properties max.poll.interval.ms=600000 # 设置为10分钟 ``` 2. **减少单次拉取的消息量** Kafka允许通过`max.poll.records`参数控制每次`poll()`方法返回的最大记录数。如果单次拉取的消息数量过多,可能会导致处理时间过长。适当减少该值可以降低单次处理的负担,从而避免消息过期。例如: ```properties max.poll.records=100 # 每次拉取最多100条消息 ``` 3. **优化消息处理逻辑** 如果消息处理逻辑本身存在性能瓶颈,如数据库写入延迟、外部服务调用慢等问题,应优先优化处理逻辑。可以考虑引入异步处理机制,将消息处理与提交Offset的操作分离,确保`poll()`方法的调用频率足够快。 4. **监控消费者滞后情况** 使用Kafka自带的监控工具或第三方监控系统,实时跟踪消费者的滞后(Lag)情况。当发现消费者滞后较高时,及时采取措施,如增加消费者实例、优化代码逻辑等。 5. **合理设置会话超时时间** `session.timeout.ms`决定了消费者与协调器(Consumer Coordinator)之间的心跳超时时间。如果消费者在该时间内未发送心跳,则会被认为已经失效,触发再平衡。合理设置该值可以避免因短暂的网络波动或处理延迟导致不必要的再平衡。例如: ```properties session.timeout.ms=45000 # 设置为45秒 ``` 6. **使用手动提交Offset** 如果使用自动提交Offset的方式,可能会因为提交间隔过长而导致Offset提交不及时。建议在处理完一批消息后,手动提交Offset,确保Offset的更新与消息处理状态保持一致。例如: ```java consumer.commitSync(); ``` ### 实践建议 - **测试与压测** 使用Kafka自带的性能测试工具`kafka-producer-perf-test.sh`和`kafka-consumer-perf-test.sh`进行压力测试,模拟高并发场景下的生产与消费行为,验证消费者的处理能力是否满足需求[^3]。 - **日志与异常处理** 在消费者代码中增加详细的日志输出,记录每次`poll()`调用的时间、处理的消息数量、提交Offset的时间等信息,便于后续分析问题。同时,捕获并处理`CommitFailedException`等异常,防止因提交失败导致消费者退出[^4]。 - **合理分配分区** Kafka中每个分区只能被一个消费者实例消费,因此消费者数量不应超过分区数。合理设置分区数可以提高并行度,从而提升整体消费能力[^2]。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值