Redis原理篇——分布式锁

Redis原理篇——分布式锁

    • 分布式锁是什么?
    • 分布式锁有哪些特性?
    • 分布式锁常用实现方式
    • Redis 实现分布式锁
      • 一、简单的 Redis 锁
      • 二、带过期时间的 Redis 锁
      • 三、加上 Owner 的 Redis 锁
      • 四、Lua 脚本确保原子性

分布式锁是什么?

分布式锁是在分布式系统中用来确保当多个进程或服务在不同的计算机上同时尝试访问和操作同一份资源时,能够协调一致地进行,避免数据冲突和不一致性的问题。

分布式锁就像是一个网络版的门卫,确保在多台计算机上运行的程序不会同时操作同一个数据。想象一下,每台计算机都要先拿到这个门卫的钥匙,才能操作数据。这样,就能防止数据混乱,确保每次只有一个程序在使用数据。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

分布式锁有哪些特性?

  • 互斥性:很好理解,确保在任何时刻,只有一个客户端可以持有锁。这意味着当一个进程或线程成功获取到锁时,其他任何尝试获取该锁的进程或线程都会被阻止,直到锁被释放。

老王进去了老李就不能再进了!!

  • 锁失效机制:为了 防止死锁,分布式锁应该具有 超时机制 。如果持有锁的进程因崩溃或其他原因未能释放锁,锁将在设定的超时时间后自动释放。

老王在里面干太久了,这不行,挂了都不知道,甭管你挂没挂,不出来拉倒,别人还要进去呐!

  • 对称性:加锁的必须和解锁的是 同一个竞争者 ,不能把其他的竞争者持有的锁给释放掉了

跟大爷打招呼,拿着钥匙进去的,得和出来的时候还钥匙的是一个人,不能老王进去老李出来吧,那不见鬼了!!

  • 高可用:需要能有一定程度的 异常处理能力 容灾能力 ,确保业务不会出现中断

保安大爷不行了,干不动了,换那个新来的大学生顶上啊!!

分布式锁常用实现方式

  • 基于缓存(如 Redis):使用缓存系统的原子操作来实现锁。例如,Redis的SETNX命令可以用来设置一个不存在的键,如果键已存在,则操作失败,这可以用来实现锁的互斥性。
  • 基于数据库:利用数据库的唯一性约束来实现锁机制。通过向数据库表中插入具有唯一索引的记录来获取锁,操作完成后删除记录来释放锁。
  • 基于Zookeeper:Zookeeper提供了一种基于临时节点和顺序节点的锁实现机制。客户端可以创建一个临时顺序节点,并检查是否为最小节点来获取锁,释放锁时删除该节点。

而本篇文章,将基于 Redis 缓存详细探讨分布式锁的使用

Redis 实现分布式锁

一、简单的 Redis 锁

想象一下,我们的系统是一个超级忙碌的酒吧,而分布式锁就是酒吧里唯一的洗手间的钥匙。客户(也就是进程)想要使用洗手间(也就是资源),他们需要先拿到钥匙。

SET restroom_key "occupied" NX

这条命令就像是在问酒保:“嘿,洗手间钥匙在吗?”如果NX(Not eXists)标志起作用,那就意味着洗手间空着,你就可以拿到钥匙(也就是锁)。如果钥匙“不存在”,那就意味着洗手间已经有人在用了,你得等等。最后,在使用完成之后会归还钥匙(delete)

不足之处

但是,如果老王进了洗手间,然后突然不见了(也就是进程崩溃了)或者没卫生纸了需要其他人递过来但又没手机(发生死锁),怎么办?我们的钥匙就永远被锁在里面了。这就引出了我们的第二部分。

二、带过期时间的 Redis 锁

为了防止洗手间被永久占用,我们给钥匙加上了一个计时器。

SET restroom_key "occupied" NX EX 5

现在,不管老王发生了什么,5分钟后钥匙也会自动回到酒保手里,其他客户就可以使用洗手间了。

进一步的不足

但是,如果老王今天身体确实不舒服,窜了太长的时间了,或者因为其他原因接个电话什么( 比如说网络延迟或者 GC卡顿等原因)导致他没消失但一直占着茅坑不拉屎,然后钥匙回到了酒保手上,另一个人老张就拿着钥匙进去了

然后关键来了,这时候老王结束了,然后出来的时候按照流程就把钥匙(也就是锁),但是实际上他还的是老张的钥匙,而这时候老张不就完犊子了,你老王的问题别把我也扯进去!!

三、加上 Owner 的 Redis 锁

分布式锁应该满足, 谁申请谁释放 的原则,不能释放别人的锁

因此我们决定在钥匙(锁)上刻上名字,这样只有名字匹配的人(一般是进程的 uuid )才能归还钥匙。

SET restroom_key “老张” NX EX 5

如果老张有了钥匙,那么只有老张能归还它。如果老王试图归还一个写着“老张”的钥匙,酒保会说:“不行,这不是你的钥匙。”

再进一步的问题

可以看到,解锁是有两个操作,先查看是否是自己的钥匙,是的话再归还钥匙(delete)

但整个解锁操作并不是原子性的,可能检查的时候是自己的,而归还删除的时候已经是别人的了( 比如说你刚获取到是自己的锁,然后处于了一个很长的 GC…)

四、Lua 脚本确保原子性

这时就需要 Lua 脚本来保证解锁的原子性,因为 Redis 在执行 Lua 脚本时,可以以原子性的方式执行,保证了锁释放操作的原子性。

// 释放锁时,先比较 unique_value 是否相等,避免锁的误释放
if redis.call("get",KEYS[1]) == ARGV[1] thenreturn redis.call("del",KEYS[1])
elsereturn 0
end

这样就通过使用 SET 命令 加上 NXEX 参数 以及 Owner 标志 和 Lua 脚本在 Redis 单节点上完成了分布式锁的加锁和解锁。

通过以上方式,分布式锁的前三个特性 互斥性 、 锁失效机制以及对称性就基本解决了,最后还有一个高可用性就放到下节讲咯 ~~

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据中台:生产制造产业链的“智慧大脑”!

在当今激烈竞争的生产制造领域,数据中台正扮演着至关重要的角色,它就像是产业链的“智慧大脑”,引领着产业的发展方向!数据中台在生产制造产业链、生态链中起到以下关键作用: 1. 数据整合与共享:将产业链各…

R可视化:R语言基础图形合集

R语言基础图形合集 欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2 基础图形可视化 数据分析的图形可视化是了解数据分布、波动和相关性等属性必…

物业客服“逆袭”记:从被质疑到被点赞,只因用了这款小程序

作为物业服务企业来说,物业客服人员是物业公司的核心部门。客服人员不仅仅要进行各部门之间的工作协调沟通,而且也是物业与业主沟通的主要桥梁。但是,往往客服人员经常被传统的报修方式所困扰,导致业主对物业客服人员存在质疑与谩…

Linux:多线程的操作

多线程操作 进程与线程线程的创建 create_pthread创建线程池给线程传入对象的指针 线程等待 pthread_join退出线程 pthread_exit线程等待参数 retval 与 线程退出参数 retval 线程中断 pthread_cancel获取线程编号 pthread_self线程分离 pthread_detach 进程与线程 进程是资源…

OpenCV读取和显示和保存图像

# 导入 OpenCV import cv2 as cv # 读取图像 image cv.imread(F:\\mytupian\\xihuduanqiao.jpg) # 创建窗口 #显示图像后,允许用户随意调整窗口大小 cv.namedWindow(image, cv.WINDOW_NORMAL) # 显示图像 cv.imshow(image, image)# 将图像保存到文件 success cv…

Linux之网络编程

Linux之网络编程 TCP协议 TCP(Transmission ControlProtocol) : 传输控制协议,是一个 面向连接的、可靠的、基于字节流的传输层的协议。TCP 协议建立的是一种点到点的,一对一的可靠连接协议 特点: 数据无丢失数据无失序数据无错误数据无重…

Zynq7000 系列FPGA模块化仪器

• 基于 XilinxXC7Z020 / 010 / 007S • 灵活的模块组合 • 易于嵌入的紧凑型外观结构 • 高性能的 ARM Cortex 处理器 • 成熟的 FPGA 可编程逻辑 ,基于 IP 核的软件库 FPGA 控制器 Zynq7000 系列模块是基于 Xilinx XC7Z020/010/007S 全可编程片上系统 (SoC) 的…

Opengauss开源4年了,都谁在向其贡献代码?

2020 年 6 月 30 日,华为将Opengauss正式开源,截止目前已经过去4年时间,社区力量对这款数据库产品都起到了哪些作用,谁的代码贡献更大一些? 根据社区官网信息统计,截止目前(2024年6月12日&…

【Java基础】OkHttp 超时设置详解

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

光纤跳线(又称光纤连接器)的种类

光纤跳线(又称光纤连接器),也就是接入光模块的光纤接头,也有好多种,且相互之间不可以互用。SFP模块接LC光纤连接器,而GBIC接的是SC光纤连接器。下面对网络工程中几种常用的光纤连接器进行详细的说明&#x…

数字化制造案例分享以及数字化制造能力评估(34页PPT)

资料介绍: 通过全面的数字化企业平台和智能制造技术的应用,制造型企业不仅提升了自身的竞争力,也为整个制造业的数字化转型提供了借鉴。同时,数字化制造能力的评估是企业实现数字化转型的关键环节,需要从技术变革、组…

【C++】STL中list的使用

前言:在前面学习的 过程中我们学习了STL中的string,vector,今天我们来进一步的学习STL中的list的使用方法。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C学习 👈 💯代…

Flowable-决策表设计器

✨✨✨ 最好用的Flowable决策表设计器 ✨✨✨ 最好用的Flowable流程设计器 本文中内容和案例出自贺波老师的书《深入Activiti流程引擎:核心原理与高阶实战》,书中的介绍更全面、详细,推荐给大家。 深入Activiti流程引擎

今年的就业环境不容乐观,你想好怎么应对了吗

今年的就业环境不容乐观,你想好怎么应对了吗 毕业生进入职场的历程往往充满挑战和未知,尤其是在当前经济环境下,失业问题愈发凸显。本文通过分享几位年轻人的真实经历,剖析大学生及职场人士面临的困境,并提供应对策略…

QT信号与槽/窗口组件优化

使用手动连接,将登录框中的取消按钮使用第二中连接方式,右击转到槽,在该槽函数中,调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中,在槽函数中判断u界面上输入的账号是否为"admin",…

简单聊一下Oracle,MySQL,postgresql三种锁表的机制,行锁和表锁

MySQL: MySQL使用行级锁定和表级锁定。行级锁定允许多个会话同时写入表,适用于多用户、高并发和OLTP应用。表级锁定只允许一个会话一次更新表,适用于只读、主要读取或单用户应用。 比如mysql开启一个窗口执行 begin; update xc_county_a…

渗透测试和红蓝对抗是什么?二者之间有何区别?

在网络安全这个庞大的体系中,渗透测试、红蓝对抗是比较常见的专业名词,承担着非常重要的作用,那么什么是渗透测试、红蓝对抗?红蓝对抗和渗透测试有什么区别?小编通过这篇文章为大家介绍一下。 渗透测试 渗透测试,是通过模拟黑…

32T存储删除视频的恢复方法

由于存储技术的发展和普及目前很多行业都开始使用小型存储,NAS可以通过网络进行数据上传和读取,使用极为方便。但是由于NAS设备容量较大且碎片较多,所以此类设备删除或者格式后恢复难度是比较大的,下边我们来分享下32T存储的恢复方…

理解查准率P、查全率R及Fβ度量怎么得来的

如果得到的是一组样本在两个算法上的一次预测结果,其中每个样本都被赋予了一个为正样本的概率(例如,通过逻辑回归或朴素贝叶斯分类器得到的概率估计),那么可以通过改变不同的阈值点来利用这些预测结果画出PR曲线。 如果…

python数据分析-房价数据集聚类分析

一、研究背景和意义 随着房地产市场的快速发展,房价数据成为了人们关注的焦点。了解房价的分布特征、影响因素以及不同区域之间的差异对于购房者、房地产开发商、政府部门等都具有重要的意义。通过对房价数据的聚类分析,可以深入了解房价的内在结构和规…