共计 1798 个字符,预计需要花费 5 分钟才能阅读完成。
背景与痛点
电商秒杀活动是典型的短时间高并发场景,往往面临三大技术挑战:

- 瞬时高并发:热门商品可能瞬间涌入数十万请求,直接压垮数据库
- 超卖问题:传统先查询后更新的非原子操作会导致库存扣减异常
- 系统雪崩:某个服务崩溃可能引发连锁反应,导致整个系统不可用
技术选型
常见解决方案对比:
- 纯数据库方案:通过事务 + 行锁实现,但 QPS 很难超过 2000,不适合秒杀场景
- 消息队列削峰:虽然能缓解压力,但实时性较差,用户体验打折扣
- Redis 单机:性能可达 10W QPS,但缺乏原子性保证
最终选择 Redis+Lua 脚本 组合,因为:
- Redis 单机性能可达 10W+ QPS
- Lua 脚本在 Redis 中原子化执行
- 支持集群部署横向扩展
核心实现
原子性库存扣减
通过 Lua 脚本实现查询 + 扣减的原子操作:
-- KEYS[1]: 商品库存 key
-- ARGV[1]: 购买数量
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock >= tonumber(ARGV[1]) then
redis.call('DECRBY', KEYS[1], ARGV[1])
return 1 -- 成功
else
return 0 -- 库存不足
end
库存预热策略
- 活动开始前 1 小时将商品库存加载到 Redis
- 采用分级缓存:
- L1:本地缓存(Caffeine)
- L2:Redis 集群
- 设置库存报警阈值,自动触发补货
分布式锁实现
使用 Redis 的 SETNX 实现购买锁:
-- KEYS[1]: 用户锁 key(userid_itemid)-- ARGV[1]: 锁超时时间(ms)
if redis.call('SETNX', KEYS[1], 1) == 1 then
redis.call('PEXPIRE', KEYS[1], ARGV[1])
return 1 -- 加锁成功
else
return 0 -- 已存在锁
end
完整代码示例
Java 调用代码(Spring Boot 环境):
@RestController
public class SkillController {
@Autowired
private StringRedisTemplate redisTemplate;
// Lua 脚本预加载
private static final String STOCK_SCRIPT =
"local stock = tonumber(redis.call('GET', KEYS[1]))\n" +
"if stock >= tonumber(ARGV[1]) then\n" +
"redis.call('DECRBY', KEYS[1], ARGV[1])\n" +
"return 1\n" +
"else\n" +
"return 0\n" +
"end";
@PostMapping("/skill")
public String skill(@RequestParam Long itemId,
@RequestParam Integer userId) {
// 1. 校验用户购买资格
// 2. 执行 Lua 脚本
Long result = redisTemplate.execute(new DefaultRedisScript<>(STOCK_SCRIPT, Long.class),
Collections.singletonList("item_stock:" + itemId),
"1" // 购买数量
);
return result == 1 ? "秒杀成功" : "库存不足";
}
}
性能优化
压测数据(单 Redis 节点)
| 并发量 | 平均响应时间 | 成功率 |
|---|---|---|
| 1000 | 15ms | 100% |
| 5000 | 28ms | 100% |
| 10000 | 41ms | 99.8% |
主要性能瓶颈出现在:
- 网络 IO(建议使用 Redis Pipeline)
- Lua 脚本复杂度(避免循环操作)
集群部署建议
- 采用 Redis Cluster 分片存储
- 每个分片配置 1 主 2 从
- 使用 Twemproxy 或 Redis Cluster 客户端做路由
避坑指南
- 脚本超时:Lua 脚本执行时间不要超过 lua-time-limit(默认 5 秒)
- 死锁风险:必须设置锁超时时间,推荐用 Redlock 算法
- 缓存穿透:对不存在的商品 ID 也进行缓存(value=null)
- 库存回滚:增加定时任务补偿异常订单
总结与展望
当前方案已能支持万级 QPS 的秒杀场景,后续可以:
- 接入 Sentinel 实现熔断降级
- 将秒杀结果异步化处理
- 结合 CDN 做静态资源加速
- 引入排队机制优化用户体验
技术没有银弹,需要根据实际业务特点持续优化。建议先在小流量场景验证,再逐步全量上线。
正文完
