Kafka解决提交位移时CommitFailedException

485 阅读2分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

这个异常发生在Consumer提交位移的时候,如果发生了不可恢复的情况,我们的Consumer端就会收到这个异常信息。我们都知道Consumer端是可以进行错误重试的,但是如果是这个异常发生,是不可以进行错误重试的。所以开发过程中,要尽量避免这个异常发生

CommitFailedException发生原因

服务端在提交位移之前,发生了重平衡,并且该提交位移的分区已经交给了其他消费者管理,所以当前消费者提交位移失败,出现这种问题的原因一般是你的消费者实例连续两次调用 poll 方法的时间间隔超过了期望的 max.poll.interval.ms 参数值。这通常表明,你的消费者实例花费了太长的时间进行消息处理,耽误了调用 poll 方法。

解决方案

合理配置参数

可以通过配置poll的最大时间间隔和减少每次poll消息的数量来避免这个异常发生。即,

  1. 增加 Consumer 端允许下游系统消费一批消息的最大时长

    配置max.poll.interval.ms参数,来增加消费者消费消息的时长,默认是5分钟。

  2. 减少下游系统一次性消费的消息总数

    通过配置max.poll.records来决定每次拉取消息的数量,默认是500条,合理的缩短每次拉取消息的数量可以解决CommitFailedException异常发生,但是如果配置的过小,势必会增加consumber与broker的交互压力。

优化业务处理

  1. 缩短单条消息处理的时间

    假如每条消息之前的平均处理时间为100ms经过优化后,每条消息的处理时间优化为了50ms这样,我们相当于程序的TPS翻了一倍,进而缩短了两次poll的时间间隔。

  2. 下游系统使用多线程来加速消费

    kafka的生产端可以多个producer同时提交消息到broker但是,每个consumber处理消息确实单线程的,一条接着一条处理,所以,所以我们可以通过改进这个消费消息的模式,引入多线程并行的去处理消息,这样便可以加快消息的处理速度。

    有关多线程开发Consumer可以参考:juejin.cn/post/698887… ,但是万事万物有利便有弊,引入多线程后,需要我们管理线程间的通讯,位移提交约定,以及多个线程的生命周期以及线程数量的管理等,所以,在引入多线程之前,一定要确认是否需要引入多线程。