← 返回首页
Kafka 如何保证消息不重复消费?
Kafka 原生只能保证 At-Least-Once(至少一次),无法完全避免重复(如消费者处理完业务但未提交 offset 就挂了)。
去重必须在业务层实现:
数据库唯一键:利用 MySQL 的唯一索引(Unique Key),插入重复数据时报错忽略。
Redis 原子操作:在处理前,先将 Message ID 存入 Redis (setnx),如果存在则跳过。
状态机:更新订单状态时带上前置状态条件(UPDATE order SET status=2 WHERE id=1 AND status=1)。
Kafka 幂等 Producer:仅能解决生产端的重复(单分区内),不能解决消费端重复。
Kafka 的消息有序性如何保证?
现状:Kafka 只保证单个 Partition 内部的消息有序,不保证 Topic 全局有序。
解决方案:
局部有序(推荐):将需要保序的同一组消息(如同一订单 ID 的操作),在发送时指定相同的 Key。Kafka 会通过 Hash(Key) 将它们路由到同一个 Partition,从而保证有序。
全局有序(不推荐):将 Topic 设置为 只有 1 个 Partition,且 Consumer 只有 1 个线程。但这会牺牲并发性能,通常不可取。
业务层排序:如果必须全局有序且高并发,可在消费者端引入内存排序或时间窗口缓冲,但复杂度极高。