redis加锁的几种方法

news2024/11/11 19:22:56

b41a464caaff4beba8b4fcbf201fd98c.jpg1. redis加锁分类

 

  redis能用的的加锁命令分表是INCR、SETNX、SET

2. 第一种锁命令INCR

  这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一。

  然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中。

 

复制代码

1、 客户端A请求服务器获取key的值为1表示获取了锁

2、 客户端B也去请求服务器获取key的值为2表示获取锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功

5、 客户端B执行代码完成,删除锁

 

$redis->incr($key);

$redis->expire($key, $ttl); //设置生成时间为1秒

复制代码

 

 

3. 第二种锁SETNX

  这种加锁的思路是,如果 key 不存在,将 key 设置为 value

  如果 key 已存在,则 SETNX 不做任何动作

 

复制代码

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

5、 客户端B执行代码完成,删除锁

 

$redis->setNX($key, $value);

$redis->expire($key, $ttl);

复制代码

 

 

4. 第三种锁SET

  上面两种方法都有一个问题,会发现,都需要设置 key 过期。那么为什么要设置key过期呢?如果请求执行因为某些原因意外退出了,导致创建了锁但是没有删除锁,那么这个锁将一直存在,以至于以后缓存再也得不到更新。于是乎我们需要给锁加一个过期时间以防不测。

  但是借助 Expire 来设置就不是原子性操作了。所以还可以通过事务来确保原子性,但是还是有些问题,所以官方就引用了另外一个,使用 SET 命令本身已经从版本 2.6.12 开始包含了设置过期时间的功能。

 

复制代码

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

5、 客户端B执行代码完成,删除锁

 

$redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒

复制代码

 

 

5. 其它问题

  虽然上面一步已经满足了我们的需求,但是还是要考虑其它问题?

  1、 redis发现锁失败了要怎么办?中断请求还是循环请求?

  2、 循环请求的话,如果有一个获取了锁,其它的在去获取锁的时候,是不是容易发生抢锁的可能?

  3、 锁提前过期后,客户端A还没执行完,然后客户端B获取到了锁,这时候客户端A执行完了,会不会在删锁的时候把B的锁给删掉?

 

6. 解决办法

  针对问题1:使用循环请求,循环请求去获取锁

  针对问题2:针对第二个问题,在循环请求获取锁的时候,加入睡眠功能,等待几毫秒在执行循环

  针对问题3:在加锁的时候存入的key是随机的。这样的话,每次在删除key的时候判断下存入的key里的value和自己存的是否一样

 

复制代码

do { //针对问题1,使用循环

    $timeout = 10;

    $roomid = 10001;

    $key = 'room_lock';

    $value = 'room_'.$roomid; //分配一个随机的值针对问题3

    $isLock = Redis::set($key, $value, 'ex', $timeout, 'nx');//ex 秒

    if ($isLock) {

        if (Redis::get($key) == $value) { //防止提前过期,误删其它请求创建的锁

          //执行内部代码

          Redis::del($key);

          continue;//执行成功删除key并跳出循环

       }

  } else {

      usleep(5000); //睡眠,降低抢锁频率,缓解redis压力,针对问题2

  }

} while(!$isLock);    

复制代码

 

 

 

7. 另外一个锁

  以上的锁完全满足了需求,但是官方另外还提供了一套加锁的算法,这里以PHP为例

 

 

 

复制代码

$servers = [

  ['127.0.0.1', 6379, 0.01],

  ['127.0.0.1', 6389, 0.01],

  ['127.0.0.1', 6399, 0.01],

];

 

$redLock = new RedLock($servers);

 

//加锁

$lock = $redLock->lock('my_resource_name', 1000);

 

//删除锁

$redLock->unlock($lock)

复制代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196366.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.4 内部类

文章目录1.概述2.特点3.内部类入门案例4.成员内部类4.1 被private修饰4.2 被static修饰5.局部内部类6.匿名内部类1.概述 如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。 就是把类定义在类的内部的情况就可以形成内部类的形式。 A类中…

【内网安全】——CS操作指南(二)

作者名:白昼安全主页面链接: 主页传送门创作初心: 一切为了她座右铭: 不要让时代的悲哀成为你的悲哀专研方向: web安全,后渗透技术每日emo:关心和细节吗?注意:我这里的cs…

Android MVI框架的使用

AndroidMviFrame AndroidMviFrame 是一个Android简单易用的项目框架 文档下面会对框架中所使用的一些核心技术进行阐述。该框架作为技术积累的产物,会一直更新维护,如果有技术方面的谈论或者框架中的错误点,可以在 GitHub 上提 Issues&…

DAMA认证(CDGA/CDGP)证书好考吗

随着数字化经济的不断发展,企业对数据重视程度越来越高,致使越来越多得数字人关注到DAMA认证。很多小伙伴都会有这样的疑问,DAMA认证(CDGA/CDGP认证)好考吗?通过率怎么样?今天小编就在这里做一下简单的说明…

UniRx之操作符详解-Linq语法

前言 UniRx中由很多操作符,注意要分为三类 Linq操作符,和Linq语法风格一致Rx操作符,从Rx.Net库继承下来的操作符。UniRx操作符,UniRx针对Unity的独有操作符。 Rx和Linq Linq是微软的一项技术,新增一种自然查询的SQ…

时间序列预测

问题简介 简单来说,时间序列是按照时间顺序,按照一定的时间间隔取得的一系列观测值,比如我们上边提到的国内生产总值,消费者物价指数,利率,汇率,股票价格等等。时间间隔可以是日,周…

数字IC设计 Synopsys EDA Tools的安装补充

数字IC Synopsys 七件套的Ubuntu安装步骤 推荐大佬的安装教程,本人亲测可用,在这里表示十分感谢! 数字IC设计的第一步——Synopsys EDA Tools的安装 跟着大佬的教程仔细点可以一步到位的! 在这里备忘本人遇到的几个粗心导致的问…

浅谈Spring IoC容器

目录 1.IoC容器 2.依赖注入 1.IoC容器 IOC: Inversion of Control,是一种设计思想。 在spring框架中,Spring 通过IoC容器进行管理所有Java对象的实例化和初始化,控制对象与对象之间的依赖关系。 IoC管理的对象称为Bean,它与使…

“华为杯”研究生数学建模竞赛2005年-【华为杯】A题:行车时间估计和最优路线选择(附获奖论文)

赛题描述 A: Highway Traveling time Estimate and Optimal Routing Ⅰ Highway traveling time estimate is crucial to travelers. Hence, detectors are mounted on some of the US highways. For instance, detectors are mounted on every two-way six-lane highways o…

MySQL 百万级数据,如何做分页查询?

随着业务的增长,数据库的数据也呈指数级增长,拿订单表为例,之前的订单表每天只有几千个,一个月下来不超过十万。而现在每天的订单大概就是2w,目前订单表的数据已经达到了700w。这带来了各种各样的问题,今天…

国产ETL工具/ETL 产品 (BeeDI ) 集团财务 双向同步 审核平台

项目需求核心 实时同步、双向同步、部分同步、日志解析同步、断点续传 项目需求概要 35分公司财务数据实时同步汇总中心平台 🔛 中心平台财务数据实时同步分发35分公司 项目需求内容 35分公司数据中部分表数据同步到中心库对应表,10张表分公司表年数…

【MyBatis】mybatis缓存机制

1. 缓存基础知识:缓存: cache缓存的作用: 通过减少IO的方式, 来提高程序的执行效率mybatis缓存包括:一级缓存: 讲话查询的数据存储到SqlSession中二级缓存: 将查询的数据存储到SqlSessionFactory中或者集成第三方的缓存: 比如EhCache...mybatis缓存只针对DQL语句, 也就是说缓存…

【1145. 二叉树着色游戏】

来源:力扣(LeetCode) 描述: 有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 root,树上总共有 n 个节点,且 n 为奇数,其中每个节点上的值从 1 到 n 各不…

WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能

很多工程软件拥有自己定义的脚本语言,作为程序员用惯了具有高亮显示和智能提示功能的编辑器,所以针对特定的脚本自己开发一个编辑器。主要采用WPF、C#语言以及AvalonEdit控件。 文章目录AvlonEdit控件实现自定义高亮显示实现文本搜索实现文本替换自定义搜…

磁疗效果因“病”而异,坚持=胜利!

磁疗在我国具有悠久的历史早在春秋战国时期,就有神医扁鹊运用磁疗治病的记载。 北京军区总医院理疗科主任,中华生物磁学研究会秘书长周万松认为,关于磁场改善血液循环这一点是肯定的,磁场可以扩张血管、加速血流、改善血液循环。但…

【H5游戏】-整一个简单的解压小游戏【抽纸巾】

专栏简介 💒个人主页 📰专栏目录 点击上方查看更多内容 📖心灵鸡汤📖社会不相信庸俗,成功需要汗水和寂寞铸就。无数次的质疑或是嘲笑,这些都无所谓,记住自己是谁,自己想要什么就…

Django的信号机制解读

Django的信号 Django的信号机制不同于Linux的信号机制,Django 中的信号用于在框架执行操作时解耦。当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作 Django的信号主要包含以下三个要素: 发送者(sender&#xff0…

网络隔离后的文件传输怎么解决?深度解析4种主流方案

网络隔离对于很多企业来说并不陌生,出于数据安全的考虑,为了隔离有害的网络和可能的网络攻击,越来越多的企业在内部进行了网络隔离。隔离的形态和方式有多种,总体上主要以物理隔离和逻辑隔离为主。网络隔离可以一定程度上甚至彻底…

功能测试环境搭建

前言新年好呀大家,大家都复工了吗~小编已经在搬砖中了😶在假期中小编学习了一点功能测试方面知识,打算写篇博客记录下来,希望这篇博客可以帮到需要的朋友。流程图一、测试计划测试计划需要在所有的测试工作之前进行,一…

HTTP协议(2)

1)当我们在浏览器上面输入一个搜狗搜索的网址之后,浏览器就会给搜狗的服务器发送了一个HTTP请求,这样咱们的搜狗的服务器就会返回一个HTTP响应; 2)当这个响应结果被浏览器解析之后,就展示成了我们目前所看到的页面内容&#xff0c…