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 真实库存
    • 创建订单记录
相关推荐
IT大白鼠4 天前
Redis 系列 · 第 01 篇——认知入门:Redis 是什么
redis·nosql
彧azz4 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
lbb 小魔仙4 天前
OpenClaw + cpolar 实战:远程 NAS、分享小游戏、RDP,再配置公网 AI 入口
数据库·人工智能·redis·oracle·prometheus
夕除4 天前
redis--018
redis
两锭子4 天前
Redis基础
redis
烟沙九洲4 天前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索4 天前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞4 天前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路5 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog5 天前
Java 接入Redis: 通用命令与键管理
java·服务器·redis