Redis 单个与多节点如何实现分布式锁
分布式锁
在许多环境中,分布式锁是非常有用的原语,在这些环境中,不同的进程必须以互斥的方式操作共享资源。在应对并发问题时,Redis 客户端还可以通过加锁的方式,来控制并发写操作对共享数据的修改,从而保证数据的正确性。
从设计建模角度来看,这三个属性是有效使用分布式锁所需的最低保证。
- 互斥性:在任何给定时刻,只有一个客户端可以持有锁。
- 无死锁:最终即使锁定资源的客户端崩溃或分区,也始终可以获取锁。
- 容错性:只要大多数 Redis 节点正常运行,客户端就可以获取和释放锁。
Redis属于分布式系统,当有多个客户端需要获取锁时,这个锁不能是某个客户端本地锁。这个锁是保存到共享的存储系统(Redis)中。可以被多个客户端共享访问、获取。 它是一个分布式锁。 不是客户端本地锁。
单实例分布式锁
Redis 使用键值对来保存锁变量,不同客户端发送的加锁和释放锁的操作请求, 这个变量名作为键值对的键,而锁变量的值,则是键值对的值: 要获取锁,方法如下: unique_value 是客户端的唯一标识,可以用一个随机生成的字符串来表示。 PX 30000 表示此锁会在30s后过期,为避免死锁问题。
- 加锁操作: 使用 SET 命令的 NX 和 EX/PX 选项。使用随机值是为了以安全的方式释放锁。当返回 OK 表示加锁成功。
# 仅当密钥尚不存在时,该命令才会设置密钥(NX选项),过期时间为 30000 毫秒(PX选项
SET distributed_lock unique_value NX PX 30000# 以下测试使用 uuidgen 生成一个随机字符串
root@ubuntu-x64_01:/opt# redis-cli --no-auth-warning -h 192.168.88.11 -p 6380 -a "******" SET distributed_lock $(uuidgen) NX PX 30000
OKroot@ubuntu-x64_01:/opt# redis-cli --no-auth-warning -h 192.168.88.11 -p 6380 -a "******" get distributed_lock
"0cde222a-bf17-4286-9a58-a886a8a8a716"
- 解锁操作:使用 lua 脚本执行解锁操作,仅当密钥存在且存储在密钥中的值正是我期望的值时才删除该密钥。当返回 1 表示解锁成功。
if redis.call("get",KEYS[1]) == ARGV[1] thenreturn redis.call("del",KEYS[1])
elsereturn 0
end# 使用 lua 脚本执行解锁操作, 持有锁客户端解锁成功返回1
root@ubuntu-x64_01:/opt# redis-cli --no-auth-warning -h 192.168.88.11 -p 6380 -a "******" --eval /opt/distributed_unlock.lua distributed_lock , 0cde222a-bf17-4286-9a58-a886a8a8a716
(integer) 1# 使用 lua 脚本执行解锁操作, 未持有锁客户端解锁失败返回0
root@ubuntu-x64_01:/opt# redis-cli --no-auth-warning -h 192.168.88.11 -p 6380 -a "******" --eval /opt/distributed_unlock.lua distributed_lock , 3e8a7cf1-424c-4bb8-ae6e-29f583c2
(integer) 0
上面的加锁操作,为避免出现死锁。我们使用了 SET 命令的 NX 和 EX/PX 选项,而不是使用 SETNX + EXPIRE ,因为 Redis 扩展了 SET 命令的参数,用这一条命令就可以实现原子性操作,否则需要考虑用LUA脚本。
“锁有效期”是我们用作密钥生存时间的时间。它既是自动释放时间,也是客户端在另一个客户端能够再次获取锁之前执行所需操作的时间,而不会在技术上违反互斥保证,互斥保证仅限于给定的窗口从获取锁的那一刻起的时间。
在释放锁操作时,客户端需要判断当前锁变量的值是否和自己持有锁的值相等。如果相等才会执行解锁操作。这样避免误释放锁的问题。
释放锁操作的逻辑包含读取锁变量、判断值是否相等、删除锁变量多个操作。为保证原子性执行,在执行时使用了LUA脚本,从而保证了锁释放操作的原子性。
分布式锁加锁和释放锁的过程,涉及多个操作,我们需要保证这些锁操作的原子性。
由于单实例节点存在单点故障,所以是否可以通过主从复制(哨兵模式),来实现分布锁的高可用? 当主节点不可用时,切换为新的主节点以维护分布锁变量 ?
这是不可行的。通过这样做,我们无法实现互斥的安全属性,因为 Redis 复制是异步的。
这是不可行的。通过这样做,我们无法实现互斥的安全属性,因为 Redis 复制是异步的。
这是不可行的。通过这样做,我们无法实现互斥的安全属性,因为 Redis 复制是异步的。
该模型存在竞争条件:
客户端1获取master中的锁。在对密钥的写入传输到副本之前,主服务器崩溃了。副本被提升为主节点。
客户端2获取对 1 已持有锁的同一资源的锁。违反安全!
有时,在特殊情况下,例如在故障期间,多个客户端可以同时持有锁是完全可以的。如果是这种情况,您可以使用基于复制的解决方案。
多实例分布式锁
Redlock 算法
该算法基本思路,假设有 5 个 Redis 主节点。这些节点是完全独立的,这里实例说明下是完全独立的,没有主从关系的。(需要在不同的计算机或虚拟机上运行 5 个 Redis master,以确保它们以基本独立的方式)。不使用复制或任何其他隐式协调系统。让客户端和多个独立的Redis依次请求加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,则认为成功获得
为了获取锁,客户端执行以下操作:
-
Step 1: 它获取当前时间(以毫秒为单位)。
-
Step 2: 它尝试在所有 N 个实例中顺序获取锁,在所有实例中使用相同的密钥名称和随机值。在步骤 2 中,在每个实例中设置锁时,客户端使用比总锁自动释放时间较小的超时来获取锁。例如,如果自动释放时间为 10 秒,则超时可能在 5-50 毫秒范围内。这可以防止客户端在尝试与已关闭的 Redis 节点通信时长时间处于阻塞状态:如果某个实例不可用,我们应该尽快尝试与下一个实例通信。
如果某个Redis实例发生故障了,为了保证Redlock算法有够继续运行,我们需要给加锁操作设置一个超时时间。 -
Step 3: 客户端通过从当前时间减去步骤 1 中获得的时间戳来计算获取锁所花费的时间。当且仅当客户端能够在大多数实例(至少 3 个)中获取锁时,并且获取锁所花费的总时间小于锁的有效时间,则认为获取了锁。
-
Step 4: 如果获取了锁,则其有效时间被视为初始有效时间减去经过的时间(如步骤 3 中计算的那样)。
如果锁的有效时间已经来不及完成共享数据的操作了,我们可以释放锁,以免出现还没完成数据操作,锁就过期了的情况。 -
Step 5: 如果客户端由于某种原因未能获取锁(要么无法锁定 N/2+1 个实例,要么有效期为负),它将尝试解锁所有实例(甚至是它认为没有锁定的实例)能够锁定)。
该算法依赖于这样的假设:虽然进程之间没有同步时钟,但每个进程中的本地时间以大致相同的速率更新,与锁的自动释放时间相比,误差幅度很小。这种假设与现实世界的计算机非常相似:每台计算机都有一个本地时钟,我们通常可以依靠不同的计算机来获得很小的时钟漂移。
此时我们需要更好地指定我们的互斥规则:只有持有锁的客户端在锁有效时间内(如步骤3中获得的)终止其工作,减去一些时间(仅几毫秒),才可以保证。以补偿进程之间的时钟漂移)。
小结
1)分布式锁不能是某个客户端本地锁,是由共享系统维护的,而Redis作为共享存储系统可以实现分布式锁。
2)分布式锁加锁和释放锁的过程,涉及多个操作,我们需要保证这些锁操作的原子性。加锁通过一条命令SET 命令的 NX 和 EX/PX 选项实现原子操作。释放锁通过lua脚本实现原子操作
3)锁变量需要设置有效时间,避免客户端发生任何异常无法解锁的情况,导致死锁。
4)通过SET命令设置锁变量时,每个客户端使用唯一值,以免出现误释放操作。
5)利用分布锁完成大部分场景应用上层[互斥]目的。把并发请求阻挡在上层,减轻对要操作的资源压力。
6) 一个分布式锁,极端情况下锁会失败,不能假设分布式锁100%安全,对于敏感业务资源层要做好兜底。
相关文章:

Redis 单个与多节点如何实现分布式锁
分布式锁 在许多环境中,分布式锁是非常有用的原语,在这些环境中,不同的进程必须以互斥的方式操作共享资源。在应对并发问题时,Redis 客户端还可以通过加锁的方式,来控制并发写操作对共享数据的修改,从而保…...

频段划分学习射频知识的意义
一、射频电路设计与低频电路设计的不同点 随着频率提高,相应电磁波的波长与变得可与分立电路元件的尺寸相比拟时,电阻、电容和电感这些元件的电响应,将偏离他们的理想频率特性。以 WIFI 2.4G 频段为例,当频率为 2437MHz࿰…...
Effective Objective-C 学习(四)
掌握GCD及操作队列的使用时机 在执行后台任务时,GCD 并不一定是最佳方式。还有一种技术叫做 NSOperationQueue,它虽然与 GCD 不同,但是却与之相关,开发者可以把操作以 NSOperation 子类的形式放在队列中,而这些操作也…...

欢迎来到IT时代----盘点曾经爆火全网的计算机电影
计算机专业必看的几部电影 计算机专业必看的几部电影,就像一场精彩的编程盛宴!《黑客帝国》让你穿越虚拟世界,感受高科技的魅力;《社交网络》揭示了互联网巨头的创业之路,《源代码》带你穿越时间解救世界,这…...

光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表
光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表 文章目录 光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表前言一、可视化工具有哪些?二、那如何做出正确可视化图表 ?GLAD原则1.G原则2.L原则3.A原则4.D原则 三、总结最后…...
如何设计出用于喜欢的界面
要设计出用户喜欢的界面,你可以考虑以下几个方面: 用户研究:首先要了解用户的需求和偏好。你可以通过用户调研、用户访谈和数据分析来获取这些信息。了解用户的行为模式、喜好和痛点,有助于设计出更吸引人的界面。 直观的布局&am…...

第三篇【传奇开心果系列】Python的文本和语音相互转换库技术点案例示例:pyttsx3实现语音助手经典案例
传奇开心果短博文系列 系列短博文目录Python的文本和语音相互转换库技术点案例示例系列 短博文目录一、项目背景和目标二、雏形示例代码三、扩展思路介绍四、与其他库和API集成示例代码五、自定义语音示例代码六、多语言支持示例代码七、语音控制应用程序示例代码八、文本转语音…...
JS中数组的常用方法
concat() 连接两个或更多的数组,并返回结果。 let array1 [1, 2, 3]; let array2 [4, 5, 6]; let concatenatedArray array1.concat(array2); console.log(concatenatedArray); // [1, 2, 3, 4, 5, 6]join() 把数组的所有元素放入一个字符串。元素通过指定…...

最好用的论文检索网站
网站展示: 网站链接 sci-hub文献检索 用途: 可以用文章的DOI来检索并下载文章...

AI专题:AI巨轮滚滚向前
今天分享的是电子系列深度研究报告:《AI专题:AI巨轮滚滚向前》。 (报告出品方:方正证券) 报告共计:65页 来源:人工智能学派 Gemini 1.5 Pro 性能显著增强,长上下文理解取得突破 …...

SpringBoot常见问题
1 引言 Spring Boot是一个基于Spring框架的快速开发脚手架,它简化了Spring应用的初始化和搭建过程,提供了众多便利的功能和特性,比如自动配置、嵌入式Tomcat等,让开发人员可以更加专注于业务逻辑的实现。 Spring Boot还提供了…...

五种多目标优化算法(MOAHA、MOGWO、NSWOA、MOPSO、NSGA2)性能对比,包含6种评价指标,9个测试函数(提供MATLAB代码)
一、5种多目标优化算法简介 1.1MOAHA 1.2MOGWO 1.3NSWOA 1.4MOPSO 1.5NSGA2 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数(zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3)ÿ…...

用 LangChain 和 Milvus 从零搭建 LLM 应用
如何从零搭建一个 LLM 应用?不妨试试 LangChain Milvus 的组合拳。 作为开发 LLM 应用的框架,LangChain 内部不仅包含诸多模块,而且支持外部集成;Milvus 同样可以支持诸多 LLM 集成,二者结合除了可以轻松搭建一个 LL…...

[Bug解决] Invalid bound statement (not found)出现原因和解决方法
1、问题描述 在写了一个很普通的查询语句之后,出现了下面的报错信息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.oauth.mapper.WxVisitorQrBeanMapper.selectByComIdAndEmpId at org.apache.ibatis.binding.Mappe…...

Qt:Qt3个窗口类的区别、VS与QT项目转换
一、Qt3个窗口类的区别 QMainWindow:包含菜单栏、工具栏、状态栏 QWidget:普通的一个窗口,什么也不包括 QDialog:对话框,常用来做登录窗口、弹出窗口(例如设置页面) QDialog实现简易登录界面…...
uni-app判断不同端
大家好,今天给大家分享的知识是在uni-app中如何区分是在什么端操作的程序 话不多说直接上代码: // #ifdef APP-PLUS<view>APP端</view>// #endif// #ifdef H5<view>H5端</view>// #endif// #ifdef MP<view>小程序端</v…...

计算机网络-网络设备防火墙是什么?
一、防火墙基本概念 前面我们学习了交换机、路由器是网络中常用的设备,现实中还有一个很重要的设备-防火墙。防火墙这一设备通常用于两个网络之间有针对性的、逻辑意义上的隔离。在网络通信领域,防火墙是一种安全设备。它用于保护一个网络区域免受来自另…...

Code Composer Studio (CCS) - Breakpoint (断点)
Code Composer Studio [CCS] - Breakpoint [断点] 1. BreakpointReferences 1. Breakpoint 选中断点右键 -> Breakpoint Properties… Skip Count:跳过断点总数,在断点执行之前设置总数 Current Count:当前跳过断电累计值 References […...

人工智能_普通服务器CPU_安装清华开源人工智能AI大模型ChatGlm-6B_001---人工智能工作笔记0096
使用centos安装,注意安装之前,保证系统可以联网,然后执行yum update 先去更新一下系统,可以省掉很多麻烦 20240219_150031 这里我们使用centos系统吧,使用习惯了. ChatGlm首先需要一台个人计算机,或者服务器, 要的算力,训练最多,微调次之,推理需要算力最少 其实很多都支持C…...
分层钱包HD钱包
bc1 开头的通常指的是比特币(Bitcoin)的地址,这种格式遵循了比特币改进提案BIP 0173中定义的Bech32编码格式。Bech32地址也被称为"SegWit"地址,它们支持Segregated Witness功能,这是比特币网络为了提高区块链…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...