redis 解决库存并发问题实现数量控制


Posted in Redis onApril 08, 2022

redis是单进程,阻塞式,在同一时刻只能处理一个请求,后来的请求需要排队等待。

优点:因为是单进程,所以无需处理并发问题,降低 系统复杂度

缺点:不适合缓存大尺寸对象(超过100kb)

原因: 由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。

而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis也在存储大数据的性能上进行了优化,但是比起Memcached,还是稍有逊色。

memcache是多进程,非阻塞式,如果仅仅作为缓存来用,可以用memcache更合适

redis 解决库存并发问题实现数量控制

一、命令

exists 查看该键key是否已存在redis中, 例如 exists mycounter

set 设置初始化一个key值 例如 set mycounter 99

get 获取一个key值 例如 getmycounter

incr 自增1 例如 incrmycounter //输出结果为100

incrby 指定增长值 例如 incrbymycounter 2 //输出结果为102

指定减少值 例如 incrbymycounter -2 //输出结果为100

setnx 当值不存在时,设置该值成功 例如 setnxmycounter 99 //输出结果为0,代表设置失败,已存在redis中

setnx key1 12 //输出结果为1,代表设置成功,之前未存在redis中

expire 设置一个键的生命周期 例如 expire mycounter 30 //设置为30秒有效期

ttl 获取key失效时间 例如 ttlmycounter //输出为 13,代表还有13秒 ,如果返回为-1,代表永不过期,永远存在redis缓存中,除非内存不足

//如果返回为-2,代表已失效,redis无该键值,可以用exists验证,返回0,代表不存

二、常见场景

商品抢购,数量没控制住,库存超限,成本不足(例如:库存1000,却被用户成功抢购2000,库存不足)

抽奖限量,没控制住,钱多花了

抢红包

三、流程图与代码

方案1 流程图:

redis 解决库存并发问题实现数量控制

方案2流程图:

redis 解决库存并发问题实现数量控制

//方案1代码,测试坏境TP5
public function redisCountV1(){
    Log::record("测试版本1并发开始", Log::INFO);
    $redis = new Redis();
    //总库存数量
    $amountLimit = 100;
    //redis存储库存键名
    $keyName = "mycounter_v6";
    //假设每次消耗库存数为1
    $incrAmount = 1;
    //判断redis中是否 存在该值,如果不存在,则用set设置(问题是如果出现并发,两个或多个用户同时访问,会导致库存重新设置)
    if(!$redis->exists($keyName)){
        $redis->set($keyName, 95);
    }
    //从redis中取出当前库存数
    $currAmount = $redis->get($keyName);
    //如果当前库存数+增长的库存数>总库存,直接返回
    if($currAmount + $incrAmount > $amountLimit) {
        file_put_contents("/Users/han/Documents/www/cs/testv1.log", "bad luck \n", FILE_APPEND);
        Log::record("bad luck", Log::INFO);
        return false;
    }
    //缓存库存数量增加
    $redis->incrby($keyName, $incrAmount);
    file_put_contents("/Users/han/Documents/www/cs/testv1.log", "good luck \n", FILE_APPEND);
    Log::record("good luck", Log::INFO);
}

//测试方式:ab  -c 100 -n 200 http://www.fenleduo.com:8080/V7/Test/redisCountV1
//方案2代码,测试坏境TP5
public function redisCountV2(){
    Log::record("测试版本2并发开始", Log::INFO);
    $redis = new Redis();
    //总库存数量
    $amountLimit = 100;
    //redis存储库存键名
    $keyName = "mycounter_v12";
    //假设每次消耗库存数为1
    $incrAmount = 1;
    //判断redis中是否 存在该值,如果不存在,则用setnx设置(注:如果出现并发,两个或多个用户同时访问,不会导致库存重新设置)
    if(!$redis->exists($keyName)){
        //setnx 如果不存在该值,则设置,如果存在则不会设置
        $redis->setnx($keyName, 95);
    }
    //从redis中取出当前库存数
    $currAmount = $redis->get($keyName);
    //如果当前库存数+增长的库存数>总库存,直接返回
    if($redis->incrby($keyName, $incrAmount) > $amountLimit) {
        file_put_contents("/Users/han/Documents/www/cs/testv2.log", "bad luck \n",FILE_APPEND);
        Log::record("bad luck", Log::INFO);
        return false;
    }
    file_put_contents("/Users/han/Documents/www/cs/testv2.log", "good luck \n",FILE_APPEND);
    Log::record("good luck", Log::INFO);
}
//测试方式:ab  -c 100 -n 200 http://www.fenleduo.com:8080/V7/Test/redisCountV2

到此这篇关于redis 解决库存并发问题实现数量控制的文章就介绍到这了,更多相关redis  库存并发内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
redis配置文件中常用配置详解
Apr 14 Redis
redis通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
Redis延迟队列和分布式延迟队列的简答实现
May 13 Redis
Java Socket实现Redis客户端的详细说明
May 26 Redis
压缩Redis里的字符串大对象操作
Jun 23 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
Redis三种集群模式详解
Oct 05 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Nov 17 Redis
一文搞懂Redis中String数据类型
Apr 03 Redis
使用Redis实现分布式锁的方法
Jun 16 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
Php获取金书网的书名的实现代码
2010/06/11 PHP
PHP中判断变量为空的几种方法分享
2013/08/26 PHP
thinkphp中字符截取函数msubstr()用法分析
2016/01/09 PHP
基于PHP实现用户在线状态检测
2020/11/10 PHP
JavaScript中的私有成员
2006/09/18 Javascript
使用jQuery fancybox插件打造一个实用的数据传输模态弹出窗体
2013/01/15 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
Nodejs实战心得之eventproxy模块控制并发
2015/10/27 NodeJs
如何让一个json文件显示在表格里【实现代码】
2016/05/09 Javascript
node简单实现一个更改头像功能的示例
2017/12/29 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
微信小程序+腾讯地图开发实现路径规划绘制
2019/05/22 Javascript
判断“命令按钮”是否被鼠标单击详解
2019/07/31 Javascript
iview实现图片上传功能
2020/06/29 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
vue swipeCell滑动单元格(仿微信)的实现示例
2020/09/14 Javascript
python进阶教程之异常处理
2014/08/30 Python
深入解析Python中的urllib2模块
2015/11/13 Python
python Django框架实现自定义表单提交
2016/03/25 Python
Python实现聊天机器人的示例代码
2018/07/09 Python
python 引用传递和值传递详解(实参,形参)
2020/06/05 Python
CSS3实现多背景模拟动态边框的效果
2016/11/08 HTML / CSS
详解HTML5 Canvas标签及基本使用
2020/01/10 HTML / CSS
Nike台湾官方商店:Nike.com (TW)
2017/08/16 全球购物
英国知名美妆护肤在线商城:Zest Beauty
2018/04/24 全球购物
澳大利亚礼品篮网站:Macarthur Baskets
2019/10/14 全球购物
党员年终民主评议的自我评价
2013/11/05 职场文书
生产班组长岗位职责
2014/01/05 职场文书
出纳会计岗位职责
2014/03/12 职场文书
教师一岗双责责任书
2014/04/16 职场文书
超市工作总结范文2014
2014/12/19 职场文书
具结保证书范本
2015/05/11 职场文书
论语读书笔记
2015/06/26 职场文书
工作建议书范文
2019/07/08 职场文书