秒杀链路中Redis与MQ如何保证事务一致性

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top

全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`

在秒杀链路中,Redis 通常用于缓存商品库存信息以提高系统响应速度,而消息队列(MQ)用于异步处理订单等后续业务,以降低系统压力。然而,由于 Redis 和 MQ 是两个独立的系统,它们之间的操作默认情况下是不具备事务一致性的。为了保证事务一致性,我们需要采取一些策略和设计模式。

保证事务一致性的策略

1. 使用事务消息

一些消息队列系统(如 Apache RocketMQ)支持事务消息。这种类型的消息可以确保消息的发送与本地事务(比如数据库操作)的执行具有原子性。

流程如下:

  • 第一步: 发送预备事务消息到 MQ。

  • 第二步: 执行本地事务(如数据库操作)。

  • 第三步: 根据本地事务的执行结果,提交或回滚预备事务消息。

如果本地事务成功,预备消息会被确认并消费;如果本地事务失败,预备消息会被回滚,消费者不会看到这条消息。

2. 基于可靠消息最终一致性

在这种方案中,系统需要保证消息的可靠投递,即使在发生故障的情况下也能最终达到一致性。

流程如下:

  • 第一步: 将消息存储在数据库中,并标记为未发送。

  • 第二步: 执行业务操作,如扣减库存。

  • 第三步: 业务操作成功后,将消息标记为已发送。

  • 第四步: 通过定时任务或事件触发机制,检查并重发那些标记为已发送但未被确认消费的消息。

3. 利用分布式事务框架

使用分布式事务框架(如 Seata)来管理跨多个资源(数据库、缓存、消息队列等)的事务。

流程如下:

  • 第一步: 开启全局事务。

  • 第二步: 执行本地事务,如更新数据库。

  • 第三步: 发送消息到 MQ。

  • 第四步: 提交或回滚全局事务。

注意事项

  • 幂等性: 确保消费者处理消息的逻辑是幂等的,即重复处理相同的消息不会导致不一致的结果。

  • 超时处理: 设计超时重试机制,对于长时间未确认的消息进行重试或报警处理。

  • 死信队列: 设置死信队列来处理无法正常消费的消息,以便进行人工干预或补偿操作。

结论

保证 Redis 与 MQ 在秒杀链路中的事务一致性需要综合考虑系统的可靠性、性能和复杂性。通常,采用事务消息、可靠消息最终一致性方案或分布式事务框架是实现一致性的有效方法。每种方法都有其适用场景和权衡,需要根据具体业务需求和系统架构来选择最合适的方案。

最后更新于