秒杀场景Redis做预扣减,问题在哪里?

Redis 做预扣减,你以为很稳,其实坑不少

秒杀场景下的库存扣减

秒杀系统的核心就是库存扣减。用户下单 → 库存减一 → 库存为零就卖完了。

问题在于:数据库扛不住高并发。几万人同时抢几百件商品,直接去 UPDATE 数据库,行锁、死锁、连接池爆满分分钟教做人。

所以常规做法是用 Redis 做预扣减------库存提前加载到 Redis,扣减发生在内存里,扛得住高并发。订单真正落库的时候再同步减数据库。

这个方案确实能抗住流量,但你得知道它有几个坑。


坑一:缓存和数据库不一致

Redis 里的库存扣了,但数据库还没来得及更新。

这时候如果消费端出了问题------比如扣了 Redis 库存,但下单失败了、支付超时了、用户取消了------Redis 里的库存就白白少了一份。

解决方式:任何导致订单失败的异常路径,都必须把 Redis 库存加回去。

库存回滚不是可选的,是必须的。漏了任何一个回滚分支,仓库里就凭空少了几个商品,少卖就少赚了。


坑二:少卖------抢到了不付钱,想买的抢不到

这是秒杀场景的一个经典困境:

A 抢到了最后一件,锁了库存。但 A 长时间不付款,订单卡在那。

B 是真心想买的,但一看没库存了,走了。

过了一阵 A 又取消订单了,库存加回去,但 B 已经不在了。最后活动结束,库存还剩几件,没人买走------少卖了。

解决方式:秒杀商品的订单有效期要大幅缩短。

普通商品可能给你 30 分钟付款,秒杀活动直接缩到 2 分钟。超时未付款自动取消订单,库存立刻回 Redis,让真正想买的人有机会。反正这几分钟你都决定不了要不要买,那就把机会让给别人。


坑三:Redis 宕机,库存数据丢了

Redis 是内存数据库,如果秒杀活动前 Redis 突然挂了,重启后内存里什么都没有。

你把库存从数据库重新加载进去?问题是------秒杀过程中已经扣减了多少,这个状态丢了。你只能从零重新开始,或者从数据库里算差值,手忙脚乱。

两个应对措施:

第一,秒杀开始前调高 AOF 刷盘频率。 默认可能是每秒刷一次,秒杀期间可以改成每条写命令都刷(appendfsync always),尽量保证数据落地。虽然性能会差一点,但压秒杀的流量 Redis 扛得住,丢数据的代价更大。

第二,上主从 + 哨兵。 主节点挂了自动切从节点,秒杀不能停。但要特别注意------异步复制下主挂了可能会有极少量数据没同步到从节点,这是 Redis 主从机制的天花板,没法完全避免。


坑四:库存 Key 变成热 Key,打爆单节点

所有用户的抢购请求都打在同一个库存 Key 上。

正常场景 Redis 完全没压力,但秒杀的第一秒,几万 QPS 全怼在同一个 Key 上,这个节点就成为了瓶颈。Redis 是单线程处理命令,一个 Key 上去了其他命令排队等,整个实例的响应延迟都被拖高。

缓解办法:

静态数据下沉到本地缓存。 商品图片、描述、封面这些不会变的东西,扔到 Caffeine 里,别每次都从 Redis 查。给库存扣减腾出带宽。

库存拆分。stock:10086 这一个 Key 拆成 10 个:stock:10086:1stock:10086:2...每个 Key 存一部分库存,请求随机打散到不同 Key 上。

但拆分有个隐藏成本------某个分片库存先耗尽了,你得立刻把请求路由到其他分片,否则用户抢着抢着发现明明总库存还有,但就是提示"已售罄"。这个路由逻辑搞复杂了反而容易出错,一般只有在 QPS 真的打到单节点天花板的时候才考虑拆库存 Key。


总结

Redis 做预扣减,常见但不是银弹:

问题 后果 解法
缓存DB不一致 多卖或少卖 异常路径必须回滚 Redis 库存
少卖 库存留到结束没人买 秒杀订单超时缩到 2 分钟
Redis 宕机丢数据 库存状态对不上 调高 AOF 频率 + 主从哨兵
热 Key 单节点被打爆 静态数据放本地缓存 + 拆分库存 Key

说到底是三件事:一致性靠回滚兜底,高可用靠主从哨兵,高性能靠本地缓存 + 必要时拆 Key。 把这三件事想清楚,Redis 预扣减方案就能用。

相关推荐
倔强的石头_19 小时前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
用户3169353811834 天前
Java连接Redis
redis
倔强的石头_4 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
冬奇Lab4 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence5 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神5 天前
三、用户与权限管理
数据库·mysql
小小工匠5 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
麦聪聊数据5 天前
数据服务化时代:企业数据能力输出的核心路径
数据库
shushangyun_5 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化