使用 Redis 实现库存扣减是一种常见的高并发场景下的解决方案,因为 Redis 作为内存数据库,具有高性能和低延迟的特点,能够快速响应库存扣减的请求。以下是一个常见的 Redis 实现库存扣减的方案:
将商品的库存信息存储在 Redis 中,每当用户下单时,通过 Redis 进行库存的扣减操作。如果库存足够,则减库存并继续后续操作;如果库存不足,则返回库存不足的提示。
初始化库存
在商品上架时,将商品的初始库存设置到 Redis 中,使用 SET
或 INCRBY
等命令。例如:
SET product_stock_1001 100 # 商品ID 1001 的库存为 100
扣减库存操作
用户发起购买请求时,使用 Redis 的原子性命令 DECR
或 DECRBY
对库存进行扣减,确保并发安全。可以用如下命令来进行库存扣减:
DECRBY product_stock_1001 1 # 购买商品 1001 的数量为 1
DECRBY
是原子操作,能够在并发场景下确保正确的库存扣减。如果库存不足(小于0),则返回错误或提示库存不足。
库存校验
在执行扣减之前或之后,检查库存是否为负数。如果结果为负数,说明库存不足,可以使用 INCRBY
恢复库存并返回错误。例如:
IF product_stock_1001 < 0 THEN
INCRBY product_stock_1001 1
RETURN '库存不足'
ELSE
CONTINUE
防止超卖
DECRBY
操作确保每次扣减时 Redis 服务器会自动判断库存是否小于零,避免多个请求同时成功扣减超出库存量。订单处理和回滚
如果库存扣减成功,接下来需要生成订单并进行支付操作。如果支付失败或订单失败,则需要回滚 Redis 中的库存,可以使用 INCRBY
将库存恢复:
INCRBY product_stock_1001 1 # 恢复之前扣减的库存
DECRBY
进行库存扣减;DECRBY
返回的库存值为负数,则恢复库存并返回库存不足;持久化问题
缓存穿透和击穿
使用 Lua 脚本保证操作原子性
示例 Lua 脚本:
local stock = redis.call('GET', KEYS[1])
if tonumber(stock) < tonumber(ARGV[1]) then
return -1
end
return redis.call('DECRBY', KEYS[1], ARGV[1])
预热库存