高并发场景下,如何避免Kafka重复消费?

重复消费是大厂经常涉及的,下面我详解Kafka重复消费解决方案@mikechen

一、先理解为什么会重复消费

Kafka 消息重复消费通常由以下几类原因导致:

高并发场景下,如何避免Kafka重复消费?-mikechen

消费者提交 Offset 失败;

消费成功后,Offset 尚未提交,服务就宕机了,重启后会重新消费;

分区重新分配时,某些消息可能被新消费者再次拉取;

业务处理成功,但提交 Offset 前失败..。等等,都会造成重复消费。

 

Kafka如何来解决?

常见实现方式:

高并发场景下,如何避免Kafka重复消费?-mikechen

 

(1)唯一业务主键去重

为每条消息生成唯一标识,例如:

订单号;

流水号;

事件 ID;

全局唯一消息 ID;

消费时先查询该 ID 是否已处理:

已处理:直接忽略;

String uniqueKey = message.getOrderId() + "_" + message.getVersion();

if (redisTemplate.opsForValue().setIfAbsent(uniqueKey, "1", 7, TimeUnit.DAYS)) {
    // 未消费过,执行业务逻辑
    processBusiness(message);
} else {
    log.info("消息已消费,跳过: {}", uniqueKey);  // 重复消费,直接忽略
}

未处理:执行业务并记录处理结果

(2)数据库唯一约束

高并发场景下,如何避免Kafka重复消费?-mikechen

将消息 ID 写入处理表,并对该字段加唯一索引。

message_id status consume_time
xxx001 1 2026-xx-xx

如果重复插入,数据库会直接拒绝。

(3)状态机控制

适用于订单、支付、库存等场景。

例如订单状态只能从“待支付”流转到“已支付”,重复消息再次执行时会因状态不匹配而被拒绝。

优点:

高并发场景下,如何避免Kafka重复消费?-mikechen

通用性强;

对 Kafka 配置依赖小;

最符合分布式系统设计原则

缺点:

需要业务系统支持;

设计复杂度相对更高。

评论交流
    说说你的看法