阿里面试:如何避免Kafka消息重复消费?

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

业务幂等(最推荐)

这是最稳定、最现实、最可控的方案,每条消息必须具备:唯一ID。

常见实现思路:

阿里面试:如何避免Kafka消息重复消费?-mikechen

唯一业务 ID + 去重存储

给每条消息带全局唯一业务 ID(订单号、支付流水号等)。

消费者处理前先查这个 ID 是否已执行过。

使用数据库去重表

设计一张表:(id PK, 消费时间, 业务状态…),插入时利用主键/唯一索引保证同一个 ID 只成功一次,失败则说明已处理过,直接跳过。

适合 QPS 不算极高,要求强一致性的场景。

使用 Redis/缓存去重

用 SETNX 或 GET+SET 的方式,以消息 ID 为 key,成功写入才继续业务逻辑,并可设置过期时间控制存储量。

适合高吞吐、对轻微不一致可容忍的场景。

 

 

幂等性生产与幂等消费者

通过在生产端启用幂等性(Kafka Producer 的 enable.idempotence=true),可以防止由于重试导致的重复写入。

阿里面试:如何避免Kafka消息重复消费?-mikechen

消费者端实现幂等处理逻辑,亦十分关键。

消费到消息时,先对消息的唯一标识。

比如:消息 key、业务 ID 或消息哈希,进行去重检查,再决定是否执行幂等的业务操作。

去重检查,可借助外部持久存储(数据库唯一索引或去重表)或缓存(如 Redis 的 SETNX)。

并确保该检查与业务写入以事务或原子操作形式完成,以避免竞态条件。

 

精确一次(Exactly-Once)

Kafka 自身提供事务机制,以支持在生产者和消费者之间实现更强的一致性保障。

阿里面试:如何避免Kafka消息重复消费?-mikechen

利用 Kafka Transactions(事务生产)结合幂等生产,可在写入多个分区或主题时保证“原子提交”。

在流处理框架(如 Kafka Streams 或支持事务的消费者实现)中,可将偏移提交包含在同一事务中,从而达到端到端的精确一次语义。

此方案适用于对一致性要求高,且能接受一定复杂度与性能开销的场景。

评论交流
    说说你的看法