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 查看所有的key方式
May 07 Redis
redis通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
基于Redis过期事件实现订单超时取消
May 08 Redis
Redis数据结构之链表与字典的使用
May 11 Redis
详解缓存穿透击穿雪崩解决方案
May 28 Redis
浅谈Redis主从复制以及主从复制原理
May 29 Redis
浅谈Redis的keys命令到底有多慢
Oct 05 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
Redis 持久化 RDB 与 AOF的执行过程
Nov 07 Redis
Redis+Lua脚本实现计数器接口防刷功能(升级版)
Feb 12 Redis
Redis命令处理过程源码解析
Feb 12 Redis
Redis分布式锁的7种实现
Apr 01 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
PHP取余函数介绍MOD(x,y)与x%y
2014/05/15 PHP
PHP中的静态变量及static静态变量使用详解
2015/11/05 PHP
关于jQuery $.isNumeric vs. $.isNaN vs. isNaN
2013/04/15 Javascript
toggle一个div显示或隐藏且可扩展成自定义下拉框
2013/09/12 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
jQuery is()函数用法3例
2014/05/06 Javascript
node.js下LDAP查询实例分享
2015/09/30 Javascript
jquery移动端TAB触屏切换实现效果
2020/12/22 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
JavaScript实现显示函数调用堆栈的方法
2016/04/21 Javascript
jquery心形点赞关注效果的简单实现
2016/11/14 Javascript
Bootstrap基本组件学习笔记之进度条(15)
2016/12/08 Javascript
js实现鼠标单击Tab表单切换效果
2018/05/16 Javascript
微信小程序支付PHP代码
2018/08/23 Javascript
微信小程序日历效果
2018/12/29 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
[02:43]2018DOTA2亚洲邀请赛主赛事首日TOP5
2018/04/04 DOTA
Tornado高并发处理方法实例代码
2018/01/15 Python
django 通过URL访问上传的文件方法
2019/07/28 Python
Django DRF路由与扩展功能的实现
2020/06/03 Python
Keras官方中文文档:性能评估Metrices详解
2020/06/15 Python
matplotlib之多边形选区(PolygonSelector)的使用
2021/02/24 Python
新西兰最大的在线设计师眼镜店:SmartBuyGlasses新西兰
2017/10/20 全球购物
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
Nike瑞士官网:Nike CH
2021/01/18 全球购物
自我评价200字分享
2013/12/17 职场文书
大学生新学期计划书
2014/04/28 职场文书
毕业生求职信
2014/06/10 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
调解书格式范本
2015/05/20 职场文书
安全生产会议制度
2015/08/06 职场文书
三年级作文之小小梦想
2019/12/06 职场文书
JavaScript实现淘宝商品图切换效果
2021/04/29 Javascript
windows安装python超详细图文教程
2021/05/21 Python
python 中的jieba分词库
2021/11/23 Python