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 24 Redis
redis 限制内存使用大小的实现
May 08 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
Redis 哨兵集群的实现
Jun 18 Redis
redis使用不当导致应用卡死bug的过程解析
Jul 01 Redis
springboot使用Redis作缓存使用入门教程
Jul 25 Redis
Redis入门教程详解
Aug 30 Redis
详解redis在微服务领域的贡献
Oct 16 Redis
聊聊redis-dump工具安装问题
Jan 18 Redis
redis 解决库存并发问题实现数量控制
Apr 08 Redis
Redis数据同步之redis shake的实现方法
Apr 21 Redis
redis lua限流算法实现示例
Jul 15 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
一个连接两个不同MYSQL数据库的PHP程序
2006/10/09 PHP
php中实现记住密码自动登录的代码
2011/03/02 PHP
php导入模块文件分享
2015/03/17 PHP
php实现猴子选大王问题算法实例
2015/04/20 PHP
Symfony2实现在doctrine中内置数据的方法
2016/02/05 PHP
laravel利用中间件做防非法登录和权限控制示例
2019/10/21 PHP
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
2013/03/04 Javascript
JavaScript事件 "事件对象"的注意要点
2016/01/14 Javascript
jQuery中on绑定事件后引发的事件冒泡问题如何解决
2016/05/25 Javascript
D3.js实现直方图的方法详解
2016/09/25 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
微信小程序 实现拖拽事件监听实例详解
2016/11/16 Javascript
Ionic 2 实现列表滑动删除按钮的方法
2017/01/22 Javascript
纯js实现页面返回顶部的动画(超简单)
2017/08/10 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
js回溯法计算最佳旅行线路代码实例
2019/09/11 Javascript
解决webpack多页面内存溢出的方法示例
2019/10/08 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
浅谈django orm 优化
2018/08/18 Python
实例讲解Python脚本成为Windows中运行的exe文件
2019/01/24 Python
详细介绍Python进度条tqdm的使用
2019/07/31 Python
django框架F&Q 聚合与分组操作示例
2019/12/12 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
时尚孕妇装:Ingrid & Isabel
2019/05/08 全球购物
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
酒店服务与管理毕业生求职信
2013/11/02 职场文书
小学英语课后反思
2014/04/26 职场文书
物业公司的岗位任命书
2014/06/06 职场文书
企业法人授权委托书
2014/09/25 职场文书
总经理助理岗位职责范本
2015/03/31 职场文书
企业法人代表证明书
2015/06/18 职场文书
教师学期述职自我鉴定
2019/08/16 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
MySQL query_cache_type 参数与使用详解
2021/07/01 MySQL