JJava 知识库
JAVA INTERVIEW

高频面试题

Redis进阶约 2 分钟

秒杀扣库存需要连续读写多个 Redis Key,你会选择事务、Lua 还是 Pipeline?

参考回答约 2 分钟 · 口语表达
我的判断

秒杀扣库存需要“读库存、判断、扣减”原子执行时选 Lua;Pipeline 只减少网络往返,事务也不提供传统数据库回滚。

如果库存和用户购买标记都在同一 Redis slot,我会用一个短 Lua 脚本完成判断、扣减和记录,Redis 执行期间不会被其他命令插入:

local stock = tonumber(redis.call("get", KEYS[1]) or "0")
if stock <= 0 then return 0 end
redis.call("decr", KEYS[1])
redis.call("sadd", KEYS[2], ARGV[1])
return 1

脚本还要先检查用户是否已购买,并保证 key 使用相同 hash tag。Lua 必须短、可超时监控,不能在里面遍历大集合。

MULTI/EXEC 能让一组命令连续执行,但错误不会像数据库事务一样自动回滚,带条件判断还常需 WATCH 重试。Pipeline 适合批量独立读写,例如预热一批 key,只优化 RTT,不保证原子性。

Redis 预扣成功后仍要发可靠消息落订单,消费端幂等,失败则补偿库存。脚本原子只覆盖 Redis 内部,不等于整个下单链路事务完成。

容易答偏踩坑误区
  • 用 Pipeline 做扣库存。 多条命令仍可能被其他请求穿插。
  • Lua 操作跨 slot key。 Cluster 下会直接失败。
  • 把复杂业务都塞进脚本。 长脚本会阻塞整个 Redis 命令执行。