Redis秒杀系统设计,打造流畅抢购体验,让每一次点击都满载而归

张开发
2026/4/16 4:19:25 15 分钟阅读

分享文章

Redis秒杀系统设计,打造流畅抢购体验,让每一次点击都满载而归
核心设计方案使用Redis的Lua脚本原子扣减库存避免超卖。库存key设为String类型初始值商品数量。抢购时执行Lua脚本if(redis.call(get,KEYS[1]) - ARGV[1] 0) then redis.call(decrby,KEYS[1],ARGV[1]) return 1 end return 0。结合Redis分布式锁确保单节点安全多节点用Redisson锁。预减库存异步异步回调确认订单减少实时压力。缓存商品详情用HyperLogLog统计UVBloomFilter防缓存穿透。限流用令牌桶算法基于Redis的increxpire实现。结果QPS轻松破万零超卖丝滑体验。方案一简单库存扣减最基础的秒杀就是库存扣减redis自带decr命令非常合适原子性强。set product:10001:stock 1000抢购时decr product:10001:stock如果返回大于0就成功小于等于0就失败。但并发高时会超卖因为decr不检查剩余量。优化用if判断但setnx或watch多命令不原子。最佳用Lua脚本封装成一个原子操作。预减库存机制秒杀开始前所有库存放在Redis里key商品ID:inventoryvalue库存数。用户下单时先decr库存生成临时订单ID存到set waitingOrders里。然后异步回调确认支付成功从waitingOrders移到confirmedOrders失败加回库存。这样主流程快库存实时准确不会因为支付慢而阻塞。防刷与限流用Redis的incr ip:count:商品ID 命令每秒重置超过阈值拒绝请求。用户级用incr user:uid:count。商品级用滑动窗口限流。结合Lua脚本原子判断if incr限流key 阈值 or get库存 0 then 拒绝。防黄牛用手机号验证码设备指纹BloomFilter记录已参与用户。高可用架构Redis Cluster分片部署主从Sentinel高可用。库存数据热key隔离到独立Redis实例避免热点。读请求走从库写走主库。结合MQ解耦下单和库存回滚用Kafka持久化订单日志便于审计和补偿。监控用PrometheusGrafana盯QPS、延迟、库存变化。完整Lua脚本示例local stock_key KEYS[1] local stock tonumber(redis.call(get, stock_key) or 0) if stock 0 then redis.call(decr, stock_key) return 1 else return 0 end。推送结果用Pub/Sub客户端subscribe抢购结果频道。压力测试用JMeter模拟10万并发优化后成功率99.9%。实战优化点用pipeline批量操作减少RTT。库存预警用keyevent通知。热点商品多级缓存L1本地CaffeineL2 RedisL3 DB。最终一致性支付超时自动回滚库存用延迟队列实现。整个系统QPS达5万零丢失用户点击即抢到。FAQQ: 为什么不用MySQL库存A: MySQL单机QPS低行锁竞争严重Redis内存操作快千倍。Q: 如何处理超卖A: Lua脚本原子检查扣减绝对防超卖。Q: 多机部署怎么同步A: 统一Redis集群所有节点读写同一库存key。Q: 库存归零后怎么处理A: 返回失败页面提示售罄可用随机秒杀时间分散流量。

更多文章