redis--011

一、传统秒杀痛点

原始流程全部压力落在 MySQL:查询库存、判断用户是否下单、扣库存、创建订单,大量并发请求直接打数据库,MySQL 扛不住高并发。

二、Redis 优化整体架构

  1. Nginx:接收前端大量请求,做负载均衡。
  2. Redis 层(Lua 脚本) :库存校验、一人一单校验、扣减库存、记录已下单用户,全部在 Redis 内部原子完成,拦截绝大部分无效请求。
  3. 阻塞队列 :Redis 校验成功后,把优惠券ID、用户ID丢入阻塞队列,直接给前端返回订单 ID。
  4. 异步消费者:后台线程从队列取出消息,异步操作 MySQL 完成真正的创建订单、扣数据库库存。

核心思想:Redis 做前置校验过滤流量,数据库异步慢处理,把高并发挡在 Redis,保护 MySQL。

三、Lua 脚本作用

Redis 单线程执行 Lua 脚本,整个脚本具备原子性,中间不会被其他命令打断,避免超卖、重复下单并发问题。

Lua 脚本业务逻辑

输入参数:voucherId优惠券ID、userId用户ID

  1. 判断库存:读取seckill:stock:{voucherId}库存值
    • 库存≤0 → 返回1,代表库存不足
  2. 判断用户是否已经抢购过:使用 Set 集合seckill:order:{voucherId}保存已下单用户 ID
    • sismember判断用户已存在 → 返回2,代表重复下单
  3. 校验全部通过:
    • incrby对库存 key 做 - 1 扣减库存
    • sadd把 userId 写入 Set 集合标记该用户已下单
    • 返回0,代表校验成功,可以下单

返回码含义

表格

返回值 含义
0 校验通过,允许下单,进入异步队列
1 库存不足
2 用户重复下单(一人一单限制)

四、完整业务执行流程

  1. 用户发起秒杀请求,进入服务。
  2. Java 调用 Redis 执行 Lua 脚本。
  3. 判断脚本返回结果:
    • 返回1/2:直接向前端返回失败提示。
    • 返回0:把业务数据放进阻塞队列,立刻返回订单 ID 给前端。
  4. 后台独立线程不断消费阻塞队列:
    • 查询数据库
    • 扣减 MySQL 真实库存
    • 创建订单记录
相关推荐
ly768913 小时前
Redis 大 Key 与热点 Key 生产治理:发现、拆分、限流与本地缓存的组合策略
redis·限流·本地缓存·大key·热点key
ShineWinsu16 小时前
对于Redis:AOF持久化的解析
linux·数据库·redis·缓存·面试·持久化·aof
仍然.16 小时前
Redis---集群
数据库·redis·缓存
hweiyu0018 小时前
Redis命令:HSCAN
redis·缓存
ly768919 小时前
Redis 分布式锁的边界条件:Redlock 争议、锁续期与客户端崩溃后的互斥失效
数据库·redis·分布式·分布式锁·watchdog·redlock
ShineWinsu1 天前
对于Redis:RDB持久化的解析
linux·数据库·redis·缓存·面试·持久化·rdb
hweiyu001 天前
Redis命令:HTTL
redis·缓存
樱花落木兰2 天前
分布式登录实战:Session 会话共享改造,Redis 存储用户登录状态
java·javascript·数据库·redis·分布式·缓存
ShineWinsu2 天前
对于Redis:Steam、Geospatial、Hyperloglog、Bitmap、Bitfield类型的解析
数据库·c++·redis·分布式·缓存·面试·zset
海绵宝宝转agent2 天前
基于Redis ZSet+AOP+注解实现限流注解算法
数据库·redis·算法