redis秒杀出现超卖现象的问题

公司做一个秒杀的活动,十来个商品,商品的限购数量不一。因为秒杀的时间是固定的早上 10 点到晚上 8 点

所以我每天早上 9 点 45 都会加库存到 redis 中

redis秒杀出现超卖现象的问题

把秒杀的商品 redis 存储起来

redis秒杀出现超卖现象的问题

然后就是秒杀了
这里先判断是不是存在在秒杀商品中

redis秒杀出现超卖现象的问题

如果是秒杀商品的话,redis 判断库存是否为 0,不为 0 减一

redis秒杀出现超卖现象的问题

前几天人数多,但是今天尤其的多,今天出现了超卖现象,redis 打印值是 0,也没变成负值。想问下这个超卖,我的方法有哪些问题导致的呢

更新一下,用了 lpush 和 rpop,仍然出现了超卖现象

redis秒杀出现超卖现象的问题

准备试试 lua

用 lua 报错了,谁能看看呀
redis秒杀出现超卖现象的问题

redis秒杀出现超卖现象的问题

颠倒的玉石
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案
  • 目测是这里出了问题

file

  • 使用 redis string 类型,存库存的数量

Laravel

  • 使用 redis list 类型

Laravel

  • redis list 类型初始化库存

Laravel

大概是这样,这是我之前测试的代码,仅供参考

2年前 评论
第二天堂 (作者) 2年前
颠倒的玉石 (楼主) 2年前
颠倒的玉石 (楼主) 2年前
第二天堂 (作者) 2年前
颠倒的玉石 (楼主) 2年前
颠倒的玉石 (楼主) 2年前
看上隔壁小花了啦 2年前
讨论数量: 33

这一步不原子

file

2年前 评论
MArtian 2年前
颠倒的玉石 (楼主) 2年前
Rache1 (作者) 2年前
颠倒的玉石 (楼主) 2年前
MArtian 2年前
Rache1 (作者) 2年前
MArtian 2年前
orange1994 2年前

理论:

a 访问 请求是 1, 同时 b 请求 也是 1

a 秒杀, b 也秒杀

最终会变成 -1 或 0,这个取决于怎么减,DECR 是 -1, set 设置会是 0

解决方法:

使用 decr 或 incr 去设置秒杀数据

INCR keyName , 不存在设置为 1,存在会 +1, 并返回数据,如图

file

判断如果大于销量,秒杀结束,否则继续,有没有超限的问题你测试下(应该不会触发)

2年前 评论
  • 目测是这里出了问题

file

  • 使用 redis string 类型,存库存的数量

Laravel

  • 使用 redis list 类型

Laravel

  • redis list 类型初始化库存

Laravel

大概是这样,这是我之前测试的代码,仅供参考

2年前 评论
第二天堂 (作者) 2年前
颠倒的玉石 (楼主) 2年前
颠倒的玉石 (楼主) 2年前
第二天堂 (作者) 2年前
颠倒的玉石 (楼主) 2年前
颠倒的玉石 (楼主) 2年前
看上隔壁小花了啦 2年前

你的 redis 操作不是原子性的,使用 lua 脚本,希望对你有帮助,自行调整

$str = <<<Lua
    local key   = KEYS[1];
    local redis_stock = redis.call('get', key);
    if (tonumber(redis_stock) > 0)
        then
            redis.call('decr', key);
            return true;
        else
            return false;
        end
Lua;
2年前 评论

不是原子操作,很简单,加锁就完了

2年前 评论
颠倒的玉石 (楼主) 2年前
Mr_Guo 2年前

好奇问一下,那你们多售的商品,就要额外垫上了吗? :joy:

2年前 评论
Diudiuuuu 2年前

之前使用过自增自减来做秒杀流程,人少确实没啥问题,但是人多必然会出现超卖问题。 我的建议是看写 LaravelCache::lock, 完整的 Lua & Redis 原子操作。

2年前 评论
颠倒的玉石 (楼主) 2年前
陈先生 (作者) 2年前
颠倒的玉石 (楼主) 2年前

要不试试用 list 往里边丢制定数量商品然后 LPOP

2年前 评论
颠倒的玉石 (楼主) 2年前

file

并发无疑是先查后改的问题,加锁要在查询的前一步加。

2年前 评论