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 相关文章推荐
在K8s上部署Redis集群的方法步骤
Apr 27 Redis
基于Redis实现分布式锁的方法(lua脚本版)
May 12 Redis
详解Redis基本命令与使用场景
Jun 01 Redis
解析高可用Redis服务架构分析与搭建方案
Jun 20 Redis
使用redis实现延迟通知功能(Redis过期键通知)
Sep 04 Redis
高并发下Redis如何保持数据一致性(避免读后写)
Mar 18 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
Redis 操作多个数据库的配置的方法实现
Mar 23 Redis
Redis数据同步之redis shake的实现方法
Apr 21 Redis
Redis基本数据类型List常用操作命令
Jun 01 Redis
Redis keys命令的具体使用
Jun 05 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
php 代码优化的42条建议 推荐
2009/09/25 PHP
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
基于jquery的3d效果实现代码
2011/03/23 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
jquery显示隐藏input对象
2014/07/21 Javascript
轻松创建nodejs服务器(2):nodejs服务器的构成分析
2014/12/18 NodeJs
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
跟我学习javascript的prototype使用注意事项
2015/11/17 Javascript
JS实现选项卡实例详解
2015/11/17 Javascript
JS提交form表单实例分析
2015/12/10 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
微信小程序实现图片自适应(支持多图)
2017/01/25 Javascript
vue2.0s中eventBus实现兄弟组件通信的示例代码
2017/10/25 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
vue 做移动端微信公众号采坑经验记录
2018/04/26 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
Windows下安装 node 的版本控制工具 nvm
2020/02/06 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
2020/04/11 Javascript
Python爬虫框架Scrapy实战之批量抓取招聘信息
2015/08/07 Python
初学python的操作难点总结(新手必看篇)
2017/08/03 Python
在Python中pandas.DataFrame重置索引名称的实例
2018/11/06 Python
Pandas库之DataFrame使用的学习笔记
2019/06/21 Python
Python中的 is 和 == 以及字符串驻留机制详解
2019/06/28 Python
python多任务之协程的使用详解
2019/08/26 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
使用CSS3配合IE滤镜实现渐变和投影的效果
2015/09/06 HTML / CSS
纯CSS3单页切换导航菜单界面设计的简单实现
2016/08/16 HTML / CSS
波兰最大的儿童服装连锁店之一:5.10.15.
2018/02/11 全球购物
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
文秘求职信范文
2014/04/10 职场文书
室内设计专业毕业生求职信
2014/05/02 职场文书
教育基金募捐倡议书
2014/05/14 职场文书
企业标语大全
2014/07/01 职场文书
银行给客户的感谢信
2015/01/23 职场文书
2019年七夕情人节浪漫祝福语大全!
2019/08/08 职场文书