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主从复制实践
May 19 Redis
redis哨兵常用命令和监控示例详解
May 27 Redis
使用redis生成唯一编号及原理示例详解
Sep 15 Redis
Redis的字符串是如何实现的
Oct 24 Redis
redis缓存存储Session原理机制
Nov 20 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
浅谈Redis跟MySQL的双写问题解决方案
Feb 24 Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Mar 17 Redis
Grafana可视化监控系统结合SpringBoot使用
Apr 19 Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 Redis
Redis Lua脚本实现ip限流示例
Jul 15 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
php trim 去除空字符的定义与语法介绍
2010/05/31 PHP
php的ajax框架xajax入门与试用介绍
2010/12/19 PHP
php+mysqli使用面向对象方式查询数据库实例
2015/01/29 PHP
Javascript hasOwnProperty 方法 & in 关键字
2008/11/26 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
Jquery为a标签的href赋值实现代码
2013/05/03 Javascript
jQuery对val和atrr("value")赋值的区别介绍
2014/09/26 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
jQuery基础知识小结
2014/12/22 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
jquery无法为动态生成的元素添加点击事件的解决方法(推荐)
2016/12/26 Javascript
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
jquery.uploadView 实现图片预览上传功能
2017/08/10 jQuery
vue动态绑定class选中当前列表变色的方法示例
2018/12/19 Javascript
python实现的二叉树算法和kmp算法实例
2014/04/25 Python
深入理解python try异常处理机制
2016/06/01 Python
Python中functools模块函数解析
2017/03/12 Python
Python面向对象编程之继承与多态详解
2018/01/16 Python
django项目搭建与Session使用详解
2018/10/10 Python
numpy linalg模块的具体使用方法
2019/05/26 Python
在Python中使用filter去除列表中值为假及空字符串的例子
2019/11/18 Python
tensorflow生成多个tfrecord文件实例
2020/02/17 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
css3 给背景设置渐变色的方法
2019/09/12 HTML / CSS
HTML5 canvas基本绘图之文字渲染
2016/06/27 HTML / CSS
VICHY薇姿美国官方网站:欧洲药房第一的抗衰老品牌
2017/11/22 全球购物
估算杭州有多少软件工程师
2015/08/11 面试题
工商管理专业职业生涯规划
2014/01/01 职场文书
新年爱情寄语
2014/04/08 职场文书
高校师德师风自我剖析材料
2014/09/29 职场文书
2015年银行柜员工作总结报告
2015/04/01 职场文书
太空授课观后感
2015/06/17 职场文书
研究生学习计划书应该怎么写?
2019/09/10 职场文书
导游词之澳门妈祖庙
2019/12/19 职场文书
Python Django项目和应用的创建详解
2021/11/27 Python
muduo TcpServer模块源码分析
2022/04/26 Redis