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

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

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

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

把秒杀的商品redis存储起来

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

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

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

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

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

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

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

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

准备试试lua

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

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

颠倒的玉石
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案
  • 目测是这里出了问题

file

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

Laravel

  • 使用redis list类型

Laravel

  • redis list类型初始化库存

Laravel

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

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

这一步不原子

file

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

理论:

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年前 评论

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

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

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

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

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

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

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

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

file

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

1年前 评论

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