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

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

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

理论:

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

a 秒杀, b 也秒杀

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

解决方法:

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

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

file

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

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

file

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

Laravel

  • 使用redis list类型

Laravel

  • redis list类型初始化库存

Laravel

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

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

你的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;
1年前 评论

这一步不原子

file

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

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

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

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

1年前 评论
Diudiuuuu 1年前
陈先生

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

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

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

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

file

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

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!