秒杀系统
画图 预热——>抢购——>下单扣库存——>支付消费——>取消订单还原库存
页面静态缓存
库存扣减
选型
redis 缓存 库存数据
- mysql 中存一条库存数据 —— 无法应对高并发场景
- mysql 中存多条库存数据 —— 先 select 再 update 并发场景下会出现 InnoDB行锁争用(甚至死锁)问题、超卖问题
-
redis 基于 incrby 原子操作 —— 解决了 超卖 和 性能 问题
- 一旦缓存丢失需要考虑恢复方案
- 初始库存 = 总的库存数 - 已消费 - 已占用
实现机制
- 并发量不高 需要使用 redis + lua脚本 实现原子性操作
- 分布式环境下需要一个分布式锁控制事务执行
业务逻辑
- 活动开始前 初始化库存
- 秒杀资格验证通过,可下单,否则立即返回错误提示
- 下单:原子性扣减库存,订单数据入 redis双队列(A、B)
- 消费:消费A队列创建订单,成功则删除B队列对应值,失败则返回提
- 校验:当A队列为空时,如果B队列有值,则说明有消费失败的情况,【?退还库存】
- 超时未支付的订单,从队列中删除 退还库存
