这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
库存扣减:高并发下的库存扣减方案
场景:50万人抢购100台iPhone 📱
想象这个场景:
秒杀开始:
- 库存:100台iPhone 15 Pro
- 参与用户:50万人
- 同时点击:10万人
问题:
- 如何确保100台iPhone正好卖给100个用户?
- 如何避免超卖(卖出101台)?
- 如何避免少卖(只卖出99台)?
这是一个经典的并发扣减库存问题!
问题演示:并发扣减库存的坑
方案一:无锁方案(最简单但会超卖)
典型输出:
🧪 测试无锁方案:
用户1: 读到库存=100
用户2: 读到库存=100
用户3: 读到库存=100
...
用户1: 购买成功!库存=99
用户2: 购买成功!库存=99 ← 两人同时买到!
用户3: 购买成功!库存=98
📊 结果:
初始库存: 100
剩余库存: 90
已售数量: 10
总交易: 20
❌ 超卖!实际售出10件,但库存只减少了10件
❌ 数据不一致!问题分析:
时间轴:
T1: 用户A读库存=100
T2: 用户B读库存=100 ← A和B读到相同的值!
T3: 用户A判断100>0,准备扣减
T4: 用户B判断100>0,准备扣减
T5: 用户A扣减库存=99
T6: 用户B扣减库存=99 ← 应该是98!
T7: 用户A创建订单
T8: 用户B创建订单 ← 两个订单,但只扣了一次库存
❌ 超卖!方案二:数据库悲观锁(可靠但性能差)
方案三:数据库乐观锁(有一定改进)
方案四:Redis原子操作(推荐方案)⚡
方案对比总结
Redis原子操作的实现细节
Lua脚本详解
Python实现
Redis vs 数据库:架构演进
想一想
问题 1:为什么Redis性能这么高?
提示:
- 内存操作 vs 磁盘操作
- 单线程无锁竞争
- 原子操作无需加锁
问题 2:Redis扣减库存后,MySQL库存如何同步?
提示:
- 异步MQ消息
- 定时对账
- 最终一致性
问题 3:Redis故障怎么办?
提示:
- Redis持久化(AOF/RDB)
- Redis集群高可用
- 故障降级方案