Kafa重复消费与消息丢失解决方案

  在使用kafka的过程中或者面试的过程中,kafka的消息重复消费问题和消息丢失问题都是比较重要的方面,这里记录一下重复消费和消息丢失的解决方案,不讲具体原理。

  • 重复消费:

    出现重复消费的场景主要有两种:一种是 Consumer 在消费过程中,应用进程被强制kill掉或者发生异常退出(挂掉…),另一种则是Consumer消费的时间过长。

    • 针对消费端挂掉等原因导致重复消费:

      • 对消息增加标识,可以保存在第三方介质中,例如:Redis,MySQL中,在处理数据之前先判断第三方介质中是否已经存在这个标识了

      • 将版本号(offset)存到消息中,在处理消息的的时候用这个版本号做乐观锁,只有当前版本号大于之前的版本号才能继续处理。

    • 针对 Consumer 消费时间过长导致的重复消费:

      • 提高单条消息的处理速度,比如对消息处理比较耗时是就可以采用异步处理或者多线程的方式处理消息
      • 根据实际场景可将 max.poll.interval.ms (等待新消息最大时长)值设置大一点,避免不必要的rebalance,此外可适当减小 max.poll.records (一次拉取消息条数)的值,默认值是500,可根据实际消息速率适当调小。
  • 消息丢失:

    消息丢失的场景在生产端和消费端都会发生,这里分别说怎么处理

    • 生产端::

      • 通过设置ACK模式来解决。0、1、-1三种模式。
        1. 0:不进行消息确认
        2. 1:leader确认即可
        3. -1:leader 和 follower 都要确认
      • 引入重试机制,设置重试次数和重试间隔
      • 采用集群,kafka的多副本机制可以保证集群的可靠新,当 leader 宕机后,会有新的 follower 选举晋升为leader
    • 消费端:

        消费端出现消息丢失问题的主要场景就是消费消息的过程中出现了异常,但是此时 offset 已经提交了,这就导致了消息丢失,这个问题也好解决,可以用下面的解决方案:

      • kafka 的 offset 提交分为 自动 和 手动 两种,而引起消息丢失大概率是因为自动提交了 offset,我们可已将 offset 设置为手动提交,在我们消费完消息,处理完业务之后在进行提交 offset 的操作。