如何解决秒杀系统中缓存扣除后意外宕机的问题?

小白在学习秒杀系统的时候遇到一个问题,一直没有办法解决,还请大神指定。
在搭建秒杀系统的时候,选择的业务逻辑为:

1、查询redis中时候有缓存的数量,如果有的话,则执行减一。如果没有的话获取分布式锁,去数据库中查询并写入缓存(分布式锁在这一步的目的为防止多个线程同时查询写入缓存)

2、如果查询到商品还有余量,则将订单信息发送到rabbitmq消息队列,消息队列异步对数据库中的数据进行更新,并生成订单。

考虑以下情况:redis缓存减一的操作和发送到消息队列的操作并不是原子性的,如果执行完缓存减一以后,突然宕机,并没有执行发送到消息队列的操作。也就是不会对数据库中的数据造成任何影响,有可能会导致少卖的问题。

这个时候根本没有执行消息队列的发送命令,也就无法通过confirm机制进行nack恢复缓存中数据。这个时候就会照成少卖的问题,请问应该如何解决?

1个回答

一般这种多阶段提交的的操作,要想办法放到同一个本地事务中,才能保证一致性,考虑到你都引用mq了,能满足最终一致性就行了。操作redis的同时,
在本地DB中做一个日志(用于异常回滚用),这两步放在一个事务里,保证同时成功,同时失败。然后发mq的操作轮询操作日志。

u012737673
明教第三十四代觉主 回复四_四: 再或者从实现方案上看,很多秒杀现在都是有预报名这种模式,并发高的环节其实是在抢座位,抢到座位的人,再去参与秒杀,压力就会小很多,这样也可以达到削峰的效果。纯个人见解,不喜勿喷,希望能帮到你
4 个月之前 回复
u012737673
明教第三十四代觉主 回复四_四: 这个类似cap一样,又要保证强一致性,又要保证高性能、高吞吐,这个很难做到,不过一般削峰限流的方式有很多,redis只是解决高并发的查询问题,建议您多上网参考下淘宝等等的秒杀设计。
4 个月之前 回复
genwin_T
四_四 您的意思是我在对redis缓存中数据更改以后,用db日志记录下来,然后发送mq的操作定时查询db日志,如果发现减了再进行发送到队列的操作吗?这样的话会不会导致缓存失去意义了,高并发的情况下,又有大量的访问打在了数据库上,而且会降低吞吐量?谢谢您
4 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐