redis锁

2023-10-27

一、redis锁的实现

加锁命令:

SETNX key value:
当键不存在时,对键进行设置操作并返回成功1,否则返回失败0。
Key是锁的唯一标识,一般按业务来决定命名;
Value 往往用来比较加锁的是哪一个线程或者哪一个消息,
一般使用UUID.randomUUID().toString()方法生成。
例如:setnx(key,1)

复制

解锁命令:

DEL key
通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。
例如:del(key)

复制

锁超时:

EXPIRE key timeout
设置 key 的超时时间,以保证即使锁没有被显式释放,
锁也可以在一定时间后自动释放,避免资源被永远锁住。
例如:expire(key,30),表示30s超时释放锁。

复制

备注:

Redis 2.6.12以上版本为set指令增加了可选参数,伪代码如下:
set(key,1,30,NX),它将加锁和超时两个动作合并到了一起,利用原子性封装了起来。

复制

二、redis锁解决的具体场景

场景1: 为什么redis锁需要设置超时?

原因分析:
1.redis与业务进程之间通常是使用网络通讯的方式进行数据加锁的,而网络通讯就存在丢包的情况。
再加上加锁和解锁是两个操作,这样就会存在锁永远不能释放的问题。
2.除此之外业务进程在加锁之后,也可能panic掉,没有办法去释放掉这个锁,导致分布式锁被永远挂住。

基于上面的两个原因:
分布式锁就需要一个超时时间来主动释放这个锁,防止分布式锁一直被挂住。

复制

redis分布式锁的解决办法,
1.通过加锁和超时两步操作来解决,不过我们最好使用set(key,1,30,NX)这种原子操作。
2.使用setnx和expire两个操作的话,因为它们不是原子性操作,也会存在上面1和2的问题,
进而导致锁被永远锁住,不过也不是没有办法,
我们可以采用lua脚本在redis上面实现的方式来保证它们的原子性。

复制

场景2: 锁超时释放了之后,加锁的业务又过来释放锁怎么办?

具体场景,进程1在超时释放了锁之后,进程2获取到了锁,后来进程1又释放锁,如此以来就有可能导致进程2没有完成就被进程1释放了锁。如下所示:

解决上面问题的关键点,在于我们在释放锁的时候,能够判断出来是不是当前加锁的进程发起的解锁操作。

一般是将进程id作为vlaue放到setnx中,在解锁之前先去判断一把这个锁是不是同一个进程的,
是就允许释放,不是就不允许解锁。

备注:这种操作其实是两步操作,判断锁,释放锁,它们并不是一个原子操作,
如此以来就存在一步操作完成,另一步没有被操作的情况。解决办法是,利用lua脚本实现锁的原子性。

复制

场景3:锁超时释放之后,会不会存在两个业务同时处理加锁的代码的情况?

这个场景与场景2是一个问题的延伸,一旦我们在设置锁的超时时间过短,就会发生这个情况。

锁在被进程2拿走之后,进程1还没有执行代码结束,
如此以来就会存在进程1和进程2同时操作那段公共代码的情况,
这样就会出问题,也显然不是我们期望的场景。

复制

对于这个场景的解决办法,往往有两个:

1.调整超时时间,让业务进程在这段时间之内一定可以执行完毕。
2.启动守护进程,在业务进程没有执行完成的时候,主动的去调节这个超时时间,
让锁的超时时间变长。

复制

场景4:锁被使用之后,其他的业务如何才能获取这个分布式锁?

这个场景,是非常基本的场景,一旦锁被进程1获取之后,在释放锁之前,进程2是怎么知道何时才能够获取到锁呢?

这个解决办法有点像操作系统的轮询和信号量两种。

1.轮询的话,就需要进程2不停的去超时加锁,直到能够加锁成功位置,
不过这种实现比较耗费服务器资源。
2.类似信号量的方法,业务进程2将加锁消息进行订阅操作,
而订阅模块会维护一个消息队列,等到锁释放之后,
便从队列中取出进程2,告知锁已经释放的通知。
进程2收到通知以后,就可以进行加锁操作了。

复制

场景5:redis是集群的话,使用redis分布式锁会不会有问题?

为了保证redis的可用性,往往redis服务器会设置主从,主从服务器中的从服务器在检测到主服务器挂掉之后,就会重新选举一个作为主服务器,而redis锁是操作在主服务器上的。

一旦,发生下面的现象:

1.主服务器刚刚被进程1加锁完成,还没有来得及同步数据到从服务器就挂掉了。
2.从服务器经过选举,选出了新的主服务器。
3.进程2在新的主服务器上加锁成功。
4.如此以来进程1和进程2都会同时操作那段公共代码,这样就会存在问题,算是加锁失败。

复制

针对这种问题,我们其实没有太好的办法,不过还好这种数据的概率比较低。

Redis 分布式锁只能作为一种缓解并发的手段,要完全解决并发问题,仍需要数据库的防并发手段配合使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

redis锁 的相关文章

随机推荐

  • boost::bind 详解

    转自 https www cnblogs com benxintuzi p 4862129 html boost bind是标准库函数std bind1st和std bind2nd的一种泛化形式 其可以支持函数对象 函数 函数指针 成员函数
  • C++ Primer阅读笔记--异常处理机制

    目录 1 异常处理机制 2 throw表达式 3 try语句块 4 标准异常类 5 代码实例 1 异常处理机制 异常处理机制为程序中的异常检测和异常处理这两部分的协作提供支持 在 C 语言中 异常处理包括 throw表达式 try语句块和异
  • GD32 低功耗模式-深度睡眠模式(包含1,2)电流达不到规格书的要求

    深度睡眠模式 深度睡眠模式1 深度睡眠模式2在测试时电流比数据手册中大得多 1 测试GD32E503RE芯片时 发现各个低功耗模式的电流分别为 run mode 3 0 3 3mA左右 sleep mode 2 4 2 5mA deepsl
  • 打包Qt 在ubuntu下运行的应用程序

    标题使用Qt Installer Framework工具进行打包Qt 在ubuntu下运行的应用程序 使用Qt Installer Framework工具进行打包 使用官网example中的tutorial 将Qt生成的应用程序拷贝到 xx
  • 当我们在地址栏输入网址并回车,这个过程都发生了啥?

    当我们在地址栏输入网址并按下回车键时 发生了以下一系列步骤 DNS解析 浏览器会提取输入的网址 URL 中的域名部分 然后通过 DNS Domain Name System 解析将域名转换为对应的 IP 地址 DNS解析是为了找到对应网站服
  • 用法char ch=getchar()正确性详解

    C陷阱与缺陷 chap5 1 include
  • Tiny Httpd在ubuntu上的运行,以及对tinyhttpd的理解

    目录 对tinyhttpd的理解 在ubuntu上运行程序 下载完成后需要对代码以及makefile进行修改 运行 首先我们了解一下相关内容 分析源码 源码顺序main gt startup gt accept request gt exc
  • android layout_torightof 代码,Android常用的布局属性

    1 background 背景 值可以是颜色值 也可以是drawable的图片资源 还可以是drawable的xml背景文件 2 layout width 和 layout height 控件的宽度 高度 可以是match parent和w
  • 技术方案书模板-1

    http www mypm net blog user1 epmt archives 2006 1544 html 1 序言 简述项目实施的必要性及意义 2 需求分析 2 1 技术现状 描述用户现有技术应用环境 人员技术状况 2 2 用户需
  • 豆瓣api不能访问了的解决办法

    在参数中添加apikey apikey 0b2bdeda43b5688921839c8ecb20399b 例如https api douban com v2 movie top250 apikey 0b2bdeda43b5688921839
  • 分布式RPC系统框架Dubbo-12服务调用超时

    服务降级的发生 其实是由于消费者调用服务超时引起的 即从发出调用请求到获取到提供者的响应结果这个时间超出了设定的时限 默认服务调用超时时限为1秒 可以在消费者端与提供者端设置超时时限 1 创建提供者工程 1 创建工程 创建provider
  • javascript 函数(function)

  • Linux CGI编程基础

    1 为什么使用CGI 如前面所见 任何的HTML均是静态网页 它无法实现一些复杂的功能 而CGI可以为我们实现 如 a 列出服务器上某个目录中的文件 对目录中的文件进行操作 b 通过CGI实现串口通讯 c 实现数据库接口 d 实现从摄像头读
  • 【数学建模竞赛】Matlab逻辑规则,结构基础及函数

    逻辑基础 逻辑变量 在Matlab中 逻辑变量是一种特殊类型的变量 用于表示逻辑值 逻辑变量只有两个可能的值 true 真 和false 假 在Matlab中 我们可以使用0和1来表示逻辑变量的值 为了定义逻辑变量 可以使用syms函数来定
  • IntelliJ IDEA WEB项目的部署配置

    摘要 非maven项目 和 maven项目部署配置的探究 Intellij IDEA Web 部署 目录 1 前言 2 项目配置 Project Structure 2 1 Project 2 2 Modules 2 3 Libraries
  • windows平台下idea打开闪退和显示已停止问题处理

    1选中idea右击兼容性疑难解答 2 选择第三个 3 选择第一个 4 点击启动程序 5 最后下一步后 记住点击保存设置 以后就可以没有问题打开了
  • 中国互联网技术联盟正式成立 京东、美团、 58到家现场分享推荐系统核心技术

    12月19日 中国技术开放日暨中国互联网技术联盟 ITA 启动仪式在北京国家会议中心举行 京东技术学院院长阿朱 原明源软件CTO 美团技术学院院长刘江 原CSDN总编 及来自联盟企业的多位CTO共同见证了这一刻 中国互联网技术联盟 ITA
  • redis触发了rdb机制,去没有自动生成dump.rdb文件

    设置触发条件 进行触发rdb机制 一开始没有在 usr local bin目录下生成dump rdb文件 后来在进入redis con文件的文件夹中 发现在这里生成了dump rdb 于是查看了redis的启动目录 后来改在 usr loc
  • kaggle房价预测特征意思_Kaggle项目之房价预测

    一 明确目的 本次练习需要围绕以下目的进行 基于竞赛方所提供的爱荷华州埃姆斯的住宅数据信息 预测每间房屋的销售价格 理解问题 观察每个变量特征的意义以及对于问题的重要程度 研究主要特征 房价 研究其他变量 研究其它变量对 房价 的影响以及它
  • redis锁

    一 redis锁的实现 加锁命令 SETNX key value 当键不存在时 对键进行设置操作并返回成功1 否则返回失败0 Key是锁的唯一标识 一般按业务来决定命名 Value 往往用来比较加锁的是哪一个线程或者哪一个消息 一般使用UU