Redis 分布式锁的作用

在单机环境下,有个秒杀商品的活动,在短时间内,服务器压力和流量会陡然上升。这个就会存在并发的问题。想要解决并发需要解决一下问题

1、提高系统吞吐率也就是qps 每秒处理的请求书

解决问题一:采用内存型数据库提高系统的qps

解决问题二:就要用到经常会遇到的锁,例如MySQL 有读锁、写锁、排他锁、悲观锁、乐观锁。不过这里只讨论redis来实现锁

简单版设置锁

$redis = new Redis();$redis->connect('127.0.0.1', 6379); //连接Redis$expire = 10;//有效期10秒$key = 'lock';//key$value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期$lock = $redis->setnx($key, $value);//判断是否上锁成功,成功则执行下步操作if(!empty($lock)){//下步操作...}

如果以这样的简单版设置锁就能解决所有问题,未免也太小看 锁 在程序中应用了。

按正常的操作示例基本上都是这样写的。但是这样写有一些问题

1、假如有10000 个请求访问了redis 不存在的键,这样请求就是指接到了MySQL数据,造成CPU短时间内达到100%甚至宕机。这样场景俗称缓存击穿造成的缓存雪崩。

解决问题:引用reids setnx 方法的作用是,当设置的key 不存在时,设置新的值。这样就避免了缓存击穿的问题。检测键的过期时间,避免产生死锁

解决死锁问题

$expire = 10;//有效期10秒    $key = 'lock';//key    $value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期    $status = true;    while($status)    {        $lock = $redis->setnx($key, $value);        if(empty($lock))        {            $value = $redis->get($key);            if($value < time())            {                $redis->del($key);            }        }else{            $status = false;            //下步操作....        }    }

2、分布式集群业务业务场景下,每台服务器是独立存在的。多台服务器怎么通过一个标识来相互竞争锁呢。这里就用到了分布式锁

这里简单介绍一下,以MYSQL 的事务机制来延生。事务四个特性ACID,有四种隔离级别:为提交读、已提交读、可重复读、串行化。这些特性都只在单台服务器上生效。到了分布式集群了,数据在不同的服务器上,紧靠事务很难保持数据的一致性及隔离性,事务的作用就意义不大了。Redis也是如此。

正确的分布式锁的打开方式

/**     * 实现Redis分布锁     */    $key        = 'demo';       //要更新信息的缓存KEY    $lockKey    = 'lock:'.$key; //设置锁KEY    $lockExpire = 10;           //设置锁的有效期为10秒    //获取缓存信息    $result = $redis->get($key);    //判断缓存中是否有数据    if(empty($result))    {        $status = TRUE;        while ($status)        {            //设置锁值为当前时间戳 + 有效期            $lockValue = time() + $lockExpire;            /**             * 创建锁             * 试图以$lockKey为key创建一个缓存,value值为当前时间戳             * 由于setnx()函数只有在不存在当前key的缓存时才会创建成功             * 所以,用此函数就可以判断当前执行的操作是否已经有其他进程在执行了             * @var [type]             */            $lock = $redis->setnx($lockKey, $lockValue);            /**             * 满足两个条件中的一个即可进行操作             * 1、上面一步创建锁成功;             * 2、   1)判断锁的值(时间戳)是否小于当前时间    $redis->get()             *      2)同时给锁设置新值成功    $redis->getset()             */            if(!empty($lock) || ($redis->get($lockKey) < time() && $redis->getSet($lockKey, $lockValue) < time() ))            {                //给锁设置生存时间                $redis->expire($lockKey, $lockExpire);                //******************************                //此处执行插入、更新缓存操作...                //******************************                //以上程序走完删除锁                //检测锁是否过期,过期锁没必要删除                if($redis->ttl($lockKey))                    $redis->del($lockKey);                $status = FALSE;            }else{                /**                 * 如果存在有效锁这里做相应处理                 *      等待当前操作完成再执行此次请求                 *      直接返回                 */                sleep(2);//等待2秒后再尝试执行操作            }        }    }

结尾

文章从知识面的广度(mysql)、示例代码优缺点的简介及应用的场景,区别于其他博客文章。嘿嘿~

更多精彩

敬请关注“PHP技术大全”微信公众号

redis setnx 分布式锁_Redis 分布式锁PHP相关推荐

  1. java redis set 过期时间_redis分布式锁自动延长过期时间

    分布式系统概念与设计(原书第5版) 93.8元 包邮 (需用券) 去购买 > 背景项目组已经有个分布式锁注解(参考前文<记一次分布式锁注解化>),但是在设置锁过期时间时,需要去预估业 ...

  2. redis 集群搭建_Redis分布式缓存分布式集群搭建

    当你试图解决一个你不理解的问题时,复杂化就产成了.-Andy Boothe Redis集群安装部署 Redis是一个运行在内存的非关系型数据库,因为其速度快(效率高),支持数据的持久化(安全),事务操 ...

  3. redis setnx 原子性_Redis从入门到深入-分布式锁(26)

    1. 分布式锁 1.1 简介 锁 是一种用来解决多个执行线程 访问共享资源 错误或数据不一致问题的工具 如果 把一台服务器比作一个房子,那么 线程就好比里面的住户,当他们想要共同访问一个共享资源,例如 ...

  4. redistemplate分布式锁实现_基于 Redis SETNX 实现分布式锁

    环境与配置 Redis 任意版本即可 SpringBoot 任意版本即可,但是需要依赖 spring-boot-starter-data-redis <dependency><gro ...

  5. redis mysql 解决超卖_Redis 分布式锁解决超卖问题

    Redis 分布式锁解决超卖问题 1,Redis 事物介绍 1. Redis 事物是可以一次执行多个命令, 本质是一组命令的集合. 2. 一个事务中的所有命令都会序列化, 按顺序串行化的执行而不会被其 ...

  6. redis 分布式锁 看门狗_redis分布式锁原理及实现

    一.写在前面 现在面试,一般都会聊聊分布式系统这块的东西.通常面试官都会从服务框架(Spring Cloud.Dubbo)聊起,一路聊到分布式事务.分布式锁.ZooKeeper等知识. 所以咱们这篇文 ...

  7. redis 失效时间单位是秒还是毫秒_redis分布式锁的这些坑,我怀疑你是假的开发...

    摘要:用锁遇到过哪些问题? 一.白话分布式 什么是分布式,用最简单的话来说,就是为了较低单个服务器的压力,将功能分布在不同的机器上面:就比如: 本来一个程序员可以完成一个项目:需求->设计-&g ...

  8. redis实现setnx,setex连用实现分布式锁

    redis实现分布式锁 1.主要命令: setnx setex 2.主要问题: 使用redis实现分布式锁,利用上面两个命令的特性.但是最重要的是锁要有过期时间,不然万一服务器宕机或者redis宕机, ...

  9. redis分布式锁实现原理_redis分布式锁实现分析与实践

    前言: 在分布式环境中, 我们有些情况下需要使用到锁进行并发控制, 可供基于的 redis, zookeeper,mysql类数据库 基于数据库类的实现是乐观锁, 基于redis,zookeeper的 ...

最新文章

  1. 漫画 | 如果程序员的妈是产品经理,她会如何逼你结婚?
  2. linux mysql 1366_Linux MySQl 5.7.17 MySQL ERROR 1366(HY000):Incorrect string value 解决方法
  3. 完整的Ubuntu18.04深度学习GPU环境配置,英伟达显卡驱动安装、cuda9.0安装、cudnn的安装、anaconda安装
  4. mysql中用HEX和UNHEX函数处理二进制数据的导入导出
  5. [渝粤教育] 西南科技大学 线性代数 在线考试复习资料
  6. 执行shell出现bad interpreter
  7. C#中 ??、 ?、 ?: 、?.、?[ ]、:
  8. WebSocket实战之————GatewayWorker使用笔记例子
  9. LeetCode 788. Rotated Digits
  10. Windows学习总结(20)——Win10 子系统Linux(Ubuntu 18.04)的安装与卸载
  11. Android 8.1 频频被曝 Bug,是要赶超苹果吗?
  12. 鸿蒙的下一个时期叫什么,华为鸿蒙,一个本属于2025年的产品
  13. 黄淮学院计算机专业录取分数线2019,黄淮学院2020年录取分数线(附2017-2020年分数线)...
  14. Vue 动态组件component
  15. 数据加密 ---- SHA 加密
  16. 目标检测--轻量级网络(截至2022-04-21)
  17. k8s执行init时出现 Initial timeout of 40s passed
  18. Burpsuit2.0系列的破解 与jdk 1.80在ubuntu下运行成功.以及代理设置ok,且burp证书导入ok,却不能访问外网的问题.
  19. python_获取两个数,打印中间值
  20. php-fpm的重启方法

热门文章

  1. java授查 非授查异常_java检查异常与非检查异常
  2. 利用SQL语句对数据进行操作:插入、更新与删除数据行
  3. 利用python进行数据分析之准备工作(1)
  4. 标记三维点_便携式3D扫描仪全自动三坐标测量机三维扫描设计扫描测量摄影
  5. 浅析python类继承(一)
  6. 定义一个类:实现功能可以返回随机的10个数字,随机的10个字母, 随机的10个字母和数字的组合;字母和数字的范围可以指定,类似(1~100)(A~z)...
  7. Oracle特殊恢复原理与实战(DSI系列)
  8. Android 中.aar文件生成方法与用法
  9. centos7.4安装nginx1.8.1 php7.7.11 安装 MySQL5.7.20
  10. 8.String、StringBuffer、enum枚举