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 相关文章推荐
详解RedisTemplate下Redis分布式锁引发的系列问题
Apr 27 Redis
基于Redis过期事件实现订单超时取消
May 08 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
浅谈Redis的几个过期策略
May 27 Redis
Redis缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
如何使用注解方式实现 Redis 分布式锁
Jul 23 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
浅谈Redis 中的过期删除策略和内存淘汰机制
一文搞懂Redis中String数据类型
Apr 03 #Redis
使用Redis做预定库存缓存功能
sentinel支持的redis高可用集群配置详解
You might like
linux命令之调试工具strace的深入分析
2013/06/03 PHP
完善CodeIgniter在IDE中代码提示功能的方法
2014/07/19 PHP
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
2015/08/23 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
基于Laravel 5.2 regex验证的正确写法
2019/09/29 PHP
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
2013/12/26 Javascript
js根据日期判断星座的示例代码
2014/01/23 Javascript
javascript正则表达式使用replace()替换手机号的方法
2015/01/19 Javascript
easyui Droppable组件实现放置特效
2015/08/19 Javascript
JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】
2016/05/10 Javascript
jQuery事件对象总结
2016/10/17 Javascript
jquery获取transform里的值实现方法
2017/12/12 jQuery
vue移动端轻量级的轮播组件实现代码
2018/07/12 Javascript
微信小程序实现循环动画效果
2018/07/16 Javascript
node.js监听文件变化的实现方法
2019/04/17 Javascript
vue+element实现表格新增、编辑、删除功能
2019/05/28 Javascript
laravel实现中文和英语互相切换的例子
2019/09/30 Javascript
深入了解Vue动态组件和异步组件
2021/01/26 Vue.js
python妙用之编码的转换详解
2017/04/21 Python
TensorFlow实现卷积神经网络CNN
2018/03/09 Python
Python批量删除只保留最近几天table的代码实例
2019/04/01 Python
python字典排序的方法
2019/10/12 Python
tensorflow 初始化未初始化的变量实例
2020/02/06 Python
Python文件操作基础流程解析
2020/03/19 Python
Python多进程multiprocessing、进程池用法实例分析
2020/03/24 Python
python 6.7 编写printTable()函数表格打印(完整代码)
2020/03/25 Python
详解CSS3开启硬件加速的使用和坑
2017/08/21 HTML / CSS
应届生新闻编辑求职信
2013/11/19 职场文书
餐饮管理自我介绍信
2014/01/15 职场文书
预备党员入党感想
2015/08/10 职场文书
毕业设计工作总结
2015/08/14 职场文书
关于教师节的广播稿
2015/08/19 职场文书
导游词之青岛太清宫
2019/12/13 职场文书
javascript遍历对象的五种方式实例代码
2021/10/24 Javascript
使用ICOM IC-R9500接收机同时测评十台收音机中波接收性能
2022/05/10 无线电
前端与RabbitMQ实时消息推送未读消息小红点实现示例
2022/07/23 Java/Android