Skip to content

7. 并发:原子、Lua、库存、限流 ​

目标:讲清 Redis 侧「并发安全」靠什么——单线程命令、Lua 脚本、正确的锁与限流,而不是在应用里瞎加锁。

相关:分布式锁 · 数据结构


原子操作 ​

单条 Redis 命令在服务端执行期间不会被其它命令打断(主线程串行执行命令)。

常用:

  • INCR / DECR / INCRBY:计数、库存粗扣
  • SET key value NX PX:加锁
  • SETNX 已不推荐单独用(易忘过期)

边界: 多条命令默认不原子。要组合逻辑 → Lua 或 Redisson 等封装。


Lua ​

Redis 执行 Lua 期间,其它命令插不进来,适合:

  • 校验 + 删除锁(防误删)
  • 扣库存:读余量 → 判断 → 扣减
  • 限流窗口内计数 + 过期

原则:

  • 脚本要短、确定性、避免大循环
  • 尽量用 EVALSHA 减网络传脚本开销
  • 不要在 Lua 里做外部 IO

库存扣减 ​

简单版(面试常答):

text
Lua / 原子:
  若 stock <= 0 → 失败
  否则 DECR → 成功

注意:

  • Redis 扣成功 ≠ 订单落库成功 → 要有对账 / 回滚库存 / 预扣+确认
  • 超卖防护在 Redis;资金与订单权威仍在 DB 事务

优化: 热点 SKU 分桶库存(sku:1001:bucket:0..N)降低单 Key 竞争;最终汇总。


限流 ​

常见:

方式思路场景
固定窗口计数INCR + 首次数 EXPIRE简单接口限流
滑动窗口ZSet 时间戳成员更平滑
令牌桶 / 漏桶应用或网关实现,Redis 存状态网关层更常见

口述:

接口限流我用 Redis 做分布式计数,Key 带用户或 IP + 接口 + 窗口;超阈值直接拒绝。要平滑再用滑动窗口;网关层限流和业务限流分层。


核心优化 ​

  1. 多步逻辑 → Lua 或成熟组件,忌客户端「先读后写」无锁
  2. 库存与订单状态机分开设计,避免「只信 Redis」
  3. 限流 Key 必须带维度与窗口,并设过期防泄漏
  4. 压测热 Key 限流/库存,必要时分片

下一步:消息 · 实战