高并发秒杀系统设计全解:从需求拆解到Redis库存实战
- Bilibili 同步视频
- 一、需求拆解:把 “大问题” 拆成 “小任务”🎯
- 🔹 商家侧核心动作
- 🔹 用户侧核心流程
- 二、架构选型:单体 vs 微服务,该怎么选?⚖️
- 1. 单体架构:小流量场景的 “简洁方案”
- ❌ 核心缺陷
- 2. 微服务架构:高并发秒杀的 “标准答案”
- ✅ 核心优势
- 架构对比 Mermaid 图
- 三、存储设计:表结构 + 数据流 + 索引优化📊
- 1. 核心数据库表设计
- 2. 索引优化:提速 10 倍 +
- 3. 秒杀全流程数据流
- 四、库存扣减:解决 “超卖” 核心难题💥
- 1. 错误示范:先查后扣,必超卖
- 2. 方案一:事务 + 行锁(不推荐)
- 3. 方案二:原子 UPDATE(推荐)
- 五、Redis 库存预热:扛住 10W+ QPS🚀
- 1. 什么是库存预热?
- 2. Redis 核心优势
- 3. 库存预热实战代码
- 六、总结:秒杀系统设计核心要点📌
Bilibili 同步视频
高并发秒杀系统设计全解:从需求拆解到Redis库存实战
在高并发电商场景下,秒杀系统堪称后端架构的 “试金石”—— 瞬间涌入的流量、严苛的一致性要求、极致的性能挑战,每一项都在考验架构设计能力。本文将从需求拆解、架构选型、存储设计、库存扣减、Redis 库存预热五大维度,从零搭建一套稳定、高效的秒杀系统。
一、需求拆解:把 “大问题” 拆成 “小任务”🎯
秒杀系统看似是一个整体功能,实则可从商家侧与用户侧双向拆解,让复杂问题清晰化:
🔹 商家侧核心动作
新建秒杀活动:创建活动基础信息
配置秒杀活动:绑定商品、设置价格、限定库存
🔹 用户侧核心流程
访问秒杀页面:高并发下页面承载能力
商品浏览:快速查询商品与活动信息
下单付款:库存扣减 + 订单生成 + 支付完成
一句话总结:秒杀的本质,是对有限库存的高并发抢夺。
二、架构选型:单体 vs 微服务,该怎么选?⚖️
面对高并发,架构直接决定系统生死。我们先对比单体架构与微服务架构的核心差异。
1. 单体架构:小流量场景的 “简洁方案”
单体架构把秒杀、商品、订单、支付全部打包在一个工程、一个数据库中,适合内部 OA、低访问系统。
❌ 核心缺陷
前后端 / 功能模块严重耦合
单模块升级需全量发布
无法单独扩容,流量集中压垮整机
代码冲突多,团队协作困难
级联故障:一个模块 Bug 导致全站宕机
数据库单点:秒杀流量打崩 DB,所有业务不可用
2. 微服务架构:高并发秒杀的 “标准答案”
微服务将大系统拆分为独立小服务,服务间解耦、数据库独立,是互联网大厂秒杀系统的标配。
✅ 核心优势
单一职责:一个服务只做一件事
灵活扩缩容:秒杀服务可单独从 10 台扩到 100 台
故障隔离:秒杀挂了不影响商品 / 订单 / 支付
技术栈自由:秒杀用 Java、订单用 Python 均可
数据库隔离:秒杀 DB 压力不扩散
架构对比 Mermaid 图
图表说明:
单体架构:所有模块共用一套数据库,流量集中、耦合度极高
微服务架构:服务与数据库一一拆分,支持独立扩容、故障隔离
三、存储设计:表结构 + 数据流 + 索引优化📊
秒杀系统的存储设计,直接影响查询速度与数据一致性。
1. 核心数据库表设计
| 表名 | 关键字段 | 作用 |
|---|---|---|
| 商品信息表 | product_id、name、price、desc | 存储商品基础信息 |
| 秒杀活动表 | seckill_id、product_id、price、count | 绑定活动与商品 |
| 库存信息表 | stock_id、product_id、seckill_id、stock、locked | 记录可售与锁定库存 |
| 订单信息表 | order_id、user_id、product_id、seckill_id、pay_status | 记录订单与支付状态 |
2. 索引优化:提速 10 倍 +
高并发查询必须加索引,否则 DB 直接被打垮:
商品表:
product_id主键索引秒杀表:
seckill_id、product_id联合索引库存表:
product_id + seckill_id唯一索引订单表:
order_id、user_id索引
3. 秒杀全流程数据流
图表说明:
商家侧:先选商品 → 创活动 → 初始化库存
用户侧:查活动 → 查商品 → 查库存 → 下单 → 扣库存
四、库存扣减:解决 “超卖” 核心难题💥
库存扣减是秒杀最容易翻车的环节,并发超卖是头号敌人。
1. 错误示范:先查后扣,必超卖
伪代码逻辑:
// 错误:查询与扣减分离,并发下失效intstock=select stock from stock_table where product_id=?and seckill_id=?;if(stock>0){update stock_table set stock=stock-1;}❌问题:最后 1 件库存,同时 2 个请求都查到 stock=1,都执行扣减,库存变为 -1,出现超卖。
2. 方案一:事务 + 行锁(不推荐)
-- 加行锁,阻塞其他请求BEGIN;SELECTstockFROMstock_tableWHEREproduct_id=?ANDseckill_id=?FORUPDATE;IFstock>0THENUPDATEstock_tableSETstock=stock-1;ENDIF;COMMIT;❌缺点:事务耗时、锁竞争激烈,高并发下 DB 直接卡死,不适合秒杀。
3. 方案二:原子 UPDATE(推荐)
-- 扣减时自带库存判断,原子操作UPDATEstock_tableSETstock=stock-1WHEREproduct_id=?ANDseckill_id=?ANDstock>0;✅优点:数据库原子性保证,无超卖,性能远高于事务。
五、Redis 库存预热:扛住 10W+ QPS🚀
数据库抗不住高并发:MySQL 单机≈1000 QPS,Redis 单机≈100000 QPS,相差 100 倍!
1. 什么是库存预热?
秒杀开始前,把库存数据提前加载到 Redis,所有查询、扣减先走 Redis,最后异步同步到 DB。
2. Redis 核心优势
内存型 NoSQL,读写速度极快
指令原子性,天然防超卖
支持 Lua 脚本,批量操作原子化
主备容灾,不丢数据
3. 库存预热实战代码
// 秒杀前:把库存写入 RedisstringRedisTemplate.opsForValue().set("seckill:stock:"+seckillId,totalStock);// 秒杀扣减:Redis 原子递减Longstock=stringRedisTemplate.opsForValue().decrement("seckill:stock:"+seckillId);if(stock<0){// 库存不足,恢复计数stringRedisTemplate.opsForValue().increment("seckill:stock:"+seckillId);return"库存不足";}// 异步同步到数据库asyncUpdateStockToDB(seckillId,productId);六、总结:秒杀系统设计核心要点📌
需求拆解:商家建活动 + 用户抢库存,分而治之
架构选择:高并发必用微服务,独立扩容、故障隔离
存储设计:四张核心表 + 精准索引,提速查询
库存扣减:用原子 UPDATE 防超卖,抛弃事务锁
流量削峰:Redis 库存预热,扛住 10W+ QPS,保护数据库
一套优秀的秒杀系统,本质是架构解耦 + 缓存提速 + 原子保证的结合体。掌握这套思路,足以应对绝大多数高并发库存场景。