一、为什么会出现重复消费的问题?
- 一个消费者组有多个消费者,每条消息只会被某个消费者的某个分区消费,如果没有正常提交offset,就会导致后续重复拉取到该消息而重复消费
- 超过
max.poll.interval.ms
时间还没消费完就会触发重平衡,就会把poll的消息(一条或多条)重新分配给其他分区消费,可能会导致重复消费 - 消费者消费完但还没来得及提交offset就宕机了,导致消息被消费了但是没记录已消费状态
- …
二、如何避免重复消费?
可以从下面几点来避免重复消费:
- 幂等性:针对每条消息生成唯一标识,存到MySQL或Redis里,每次消费前先判断该消息是否已消费国
- 减少poll数量:减少消费者一次性批量拉取的消息条数,提高消费速率,减少出现消费超时的情况
- 调整消费超时时间:合理调整
max.poll.interval.ms
参数,避免消费超时而触发重平衡 - 提高消费速率:提高消费者的消费速率,避免阻塞太久而超时
- 手动提交offset:确保每次消费都手动提交offset,不会重复拉取到同条消息
- …