Redis-分布式锁!

分布式锁,顾名思义,分布式锁就是分布式场景下的锁,比如多台不同机器上的进程,去竞争同一项资源,就是分布式锁。

分布式锁特性

互斥性:锁的目的是获取资源的使用权,所以只让一个竞争者持有锁,这一点要尽可能保证;

安全性:避免锁因为异常永远不被释放。当一个竞争者在持有锁期间内,由于意外崩溃而导致未能主动解锁,其持有的锁也能够被兜底释放,并保证后续其它竞争者也能加锁;

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

可靠性:需要有一定程度的异常处理能力、容灾能力。
 

分布式锁的实现

 

1.直接用Redis的setnx命令

首先,当然是搭建一个最简单的实现方式, 直接用Redis的setnx命令, 这个命令的语法是: setnx key value如果key不存在,则会将key设置为value,并返回1;如果key存在,不会有任务影响,返回0。
基于这个特性,我们就可以用setnx实现加锁的目的:通过setnx加锁,加锁之后其他服务无法加锁,用完之后,再通过delete解锁

就是这个获取锁的过程就是setnx的过程 如果有锁了 那就会返回0 如果没锁 就会把key设置为value然后释放锁就会delete

2.支持过期时间

最简化版本有一个问题:如果获取锁的服务挂掉了,那么锁就一直得不到释放,就像石沉大海,查无音信。所以,我们需要一个超时来兜底。
Redis中有expire命令,用来设置一个key的超时时间。 但是setnx和expire不具备 原子性,如果setnx获取锁之后,服务挂掉(还没来的及设置时间),依旧是泥牛入海。
很自然,我们会想到,set和expire, 有没有原子操作?
当然有,Redis早就考虑到了这种场景,推出了如下执行语句: set key value nx ex seconds nx表示具备setnx特定,ex表示增加了过期时间,最后一个参数就是过期时间的值。

他把set和expire合成了一个原子操作

这个过期和释放锁是并列的 就是主动释放锁和过期都会delete

3.加上Owner

我们来试想一下如下场景:服务A获取了锁,由于业务流程比较长,或者网络延迟、GC卡顿等原因,导致锁过期,而业务还会继续进行。这时候,业务B已经拿到了锁,准备去执行,这个时候服务A恢复过来并做完了业务,就会释放锁,而B却还在继续执行。
在真实的分布式场景中,可能存在几十个竞争者,那么上述情况发生概率就很高,导致同一份资源频繁被不同竞争者同时访问,分布式锁也就失去了意义
基于这个场景,我们可以发现,问题关键在于,竞争者可以释放其他人的锁。(也就是说 只能这个锁持有者自己释放了锁才行 就是这个delete过程 只能自己来删除 而不能其他线程删除)那么在异常情况下,就会出现问题,所以我们可以进一步给出解决方案: 分布式锁需要满足谁申请谁释放原则,不能释放别人的锁,也就是说,分布式锁,是要有归属的。

我们获取锁之前不是会有一个delete释放锁的过程吗? 我们让其他线程没法执行这个delete操作 只有我锁持有者可以delete

具体步骤 释放前先检测是否是持有者要delete 然后返回检查结果 然后再根据结果进行操作


4.引入LUA


释放前先检测是否是持有者要delete 然后返回检查结果 然后再根据结果进行操作

这三步不是原子的

我们来看 检测和返回结果之间的间隙

这个同时锁过期了 

检测 这锁过期释放了锁 且有其他客户端获取到了锁 然后返回结果  删除锁 

这个时候 已经判断完了它是自己的锁 他就会删除这个锁

这就造成了锁的误删

然后LUA给这仨操作合成原子操作了

(其实owner )

分布式锁的可靠性靠什么保证

主从容灾

emmm 就是主库寄了 用从库顶一顶先

但是主从切换,需要人工参与,会提高人力成本。不过Redis已经有成熟的解决方案,也就是哨兵模式,可以灵活自动切换,不再需要人工介入。

一堆箭头乱七八糟的 描述一下 每个哨兵会监视其他两个哨兵的 同时还会监视主库和两个从库 

通过增加从节点的方式,虽然一定程度解决了单点的容灾问题,但并不是尽善尽美的,由于同步有时延,Slave可能会损失掉部分数据,分布式锁可能失效,这就会发生短暂的多机获取到执行权限。

更妥善的方法

多机部署

如果对一致性的要求高一些, 可以尝试多机部署,比如Redis的RedLock, 大概的思路就是多个机器,通常是奇数个,达到一半以上同意加锁才算加锁成功,这样,可靠性会向ETCD靠近。
现在假设有5个Redis主节点,基本保证它们不会同时宕掉,获取锁和释放锁的过程中,客户端会执行以下操作:
1.向5个Redis申请加锁;
2.只要超过一半,也就是3个Redis返回成功,那么就是获取到了锁。如果超过一半失败, 需要向每个Redis发送解锁命令;
3.由于向5个Redis发送请求,会有一定时耗,所以锁剩余持有时间,需要减去请求时间。这个可以作为判断依据,如果剩余时间已经为0,那么也是获取锁失败:
4.使用完成之后,向5个Redis发送解锁请求。
这种模式的好处在于,如果挂了2台Redis,整个集群还是可用的,给了运维更多时间来修复。

(这种方法太重了 业务很少会用的到)

 

分布式系统三大困境

简称NPC

这种模式的好处在于,如果挂了2台Redis,整个集群还是可用的,给了运维更多时间来修复。
另外,多说一句,单点Redis的所有手段,这种多机模式都可以使用,比如为每个节点配置哨兵模式,由于加锁是
-半以上同意就成功,那么如果单个节点进行了主从切换,单个节点数据的丢失,就不会让锁失效了。这样增强了
可靠性。
N:Network Delay (网络延迟)当分布式锁获得返回包的时间过长,此时可能虽然加锁成功,但是已经时过境迁,锁可能很快过期。RedLock算 了做了些考量,也就是前面所说的锁剩余持有时间,需要减去请求时间,如此一来,就可以一定程度解决网络延迟的问题。
P: Process Pause (进程暂停)比如发生GC,获取锁之后GC了,处于GC执行中,然后锁超时。其他锁获取,这种情况几乎无解。这时候GC回来了,那么两个进程就获取到了同一个分布式锁。

也许你会说,在GC回来之后,可以再去查一次啊?
这里有两个问题,首先你怎么知道GC回来了?这个可以在做业务之前,通过时间,进行一个粗略判断,但也是很吃场景经验的;第二,如果你判断的时候是ok的,但是判断完GC了呢?这点RedLock是无法解决的。
 

C: Clock Drift (时钟漂移)
如果竞争者A,获得了RedLock,在5台分布式机器上都加上锁。为了方便分析,我们直接假设5台机器都发生了时钟漂移,锁瞬间过期了。这时候竞争者B拿到了锁,此时A和B拿到了相同的执行权限。
根据上述的分析.可以看出,RedLock也不能扛住NPC的挑战,因此,单单从分布式锁本身出发,完全可靠是不可能的。要实现一个相对可靠的分布式锁机制,还是需要和业务的配合,业务本身要幂等可重入,这样的设计可以省却很多麻烦。
 

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

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

相关文章

三分之一的英国大学生被欺诈

根据NatWest的一项新研究,去年英国大学三分之一的学生在网上遭遇欺诈。 今年5月,这家高街银行委托咨询公司RedBrick对来自63个城镇的3000多名英国大学生进行了调查。 尽管三分之一的受访者表示他们在过去的12个月里遇到过诈骗,但没有统计数…

【Unity每日一记】资源加载相关你掌握多少?

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

opencv进阶08-K 均值聚类cv2.kmeans()介绍及示例

K均值聚类是一种常用的无监督学习算法,用于将一组数据点分成不同的簇(clusters),以便数据点在同一簇内更相似,而不同簇之间差异较大。K均值聚类的目标是通过最小化数据点与所属簇中心之间的距离来形成簇。 当我们要预测…

【C++学习手札】一文带你初识C++继承

食用指南:本文在有C基础的情况下食用更佳 🍀本文前置知识: C类 ♈️今日夜电波:napori—Vaundy 1:21 ━━━━━━️💟──────── 3:23 …

英语学习 Eudic欧路词典 for Mac

欧路词典是一款功能强大的英语学习工具,其多语种支持、海量词库、强大的翻译功能、听力训练和生词本和笔记等特点,使得用户可以方便地进行英语学习和提高英语水平,适用于各种英语学习人员和文化交流人员等不同人群。 1 、全面支持最新Retina…

《cpolar内网穿透》外网SSH远程连接linux(CentOS)服务器

本次教程我们来实现如何在外公网环境下,SSH远程连接家里/公司的Linux CentOS服务器,无需公网IP,也不需要设置路由器。 视频教程 [video(video-jrpesBrv-1680147672481)(type-csdn)(url-CSDN直播https://live-file.csdnimg.cn/release/live/…

[oneAPI] 手写数字识别-LSTM

[oneAPI] 手写数字识别-LSTM 手写数字识别参数与包加载数据模型训练过程结果 oneAPI 比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolk…

5G无人露天矿山解决方案

1、5G无人露天矿山解决方案背景 ①2010.10,国家安监总局《金属非金属地下矿山安全避险“六大系统”安装使用和监督检查暂行规定》 ②2016.03,国家发改委《能源技术革命创新行动计划(2016-2030)》,2025 年重点煤矿区采…

6.1 安全漏洞与网络攻击

数据参考:CISP官方 目录 安全漏洞及产生原因信息收集与分析网络攻击实施后门设置与痕迹清除 一、安全漏洞及产生原因 什么是安全漏洞 安全漏洞也称脆弱性,是计算机系统存在的缺陷 漏洞的形式 安全漏洞以不同形式存在漏洞数量逐年递增 漏洞产生的…

强化学习:用Python训练一个简单的机器人

一、介绍 强化学习(RL)是一个令人兴奋的研究领域,它使机器能够通过与环境的交互来学习。在这篇博客中,我们将深入到RL的世界,并探索如何使用Python训练一个简单的机器人。在本文结束时,您将对 RL 概念有基本…

Qt 杂项(Qwt、样式等)

Qt隐藏窗口边框 this->setWindowFlags(Qt::FramelessWindowHint);Qt模态框 this->setWindowModality(Qt::ApplicationModal);QLable隐藏border 代码中设置 lable->setStyleSheet("border:0px");或者UI中直接设置样式:“border:0px” Qwt开源…

什么是DNS服务器的层次化和分布式?

DNS (Domain Name System) 的结构是层次化的,意味着它是由多个级别的服务器组成,每个级别负责不同的部分。以下是 DNS 结构的层次: 根域服务器(Root Servers): 这是 DNS 层次结构的最高级别。全球有13组根域…

chrome解决http自动跳转https问题

1.地址栏输入: chrome://net-internals/#hsts 2.找到底部Delete domain security policies一栏,输入想处理的域名,点击delete。 例如我之前可能访问过这个网址,https://test.apac.com:9090/login 但是后面我去掉了https协议&…

Patch SCN一键解决ORA-600 2662故障---惜分飞

客户强制重启库之后,数据库启动报ORA-600 2037,ORA-745 kcbs_reset_pool/kcbzre1等错误 Wed Aug 09 13:25:38 2023 alter database mount exclusive Successful mount of redo thread 1, with mount id 1672229586 Database mounted in Exclusive Mode Lost write protection d…

ArcGIS 利用cartogram插件制作变形地图

成果图 注:本图数据并不完全对,只做为测试用例 操作 首先需要下载一个插件cartogram 下载地址在这里 https://www.arcgis.com/home/item.html?idd348614c97264ae19b0311019a5f2276 下载完毕之后解压将Cartograms\HelpFiles下的所有文件复制到ArcGIS…

NFT Insider#102:The Sandbox重新上线LAND桥接服务,YGG加入Base生态

引言:NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto(https://twitter.com/beep_crypto)联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周…

【npm run dev报错】无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。

1.winX键,使用管理员身份运行power shell 2.输入命令:set-executionpolicy remotesigned 3.输入”Y“,回车,问题解决。 文章来源:无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。 - 前…

java之juc二

JMM 请你谈谈对Volatile的理解 Volatile是jvm提供的轻量级的同步机制(和synchronized差不多,但是没有synchronized那么强大) 保证可见性不保证原子性禁止指令重排 什么是JMM JMM:java内存模型,不存在的东西&#…

Linux 修改信号的响应方式

修改信号的响应方式 1.signal()方法介绍: 修改信号的响应方式要用到方法signal()。需要引用头文件signal.h。signal()的原型: typedef重命名了一个函数指针的类型,这个指针的类型为指向一个参数为int返回值为void的函数的指针。这个函数指针…

小白到运维工程师自学之路 第七十三集 (kubernetes应用部署)

一、安装部署 1、以Deployment YAML方式创建Nginx服务 这个yaml文件在网上可以下载 cat nginx-deployment.yaml apiVersion: apps/v1 #apiVersion是当前配置格式的版本 kind: Deployment #kind是要创建的资源类型,这里是Deploymnet metadata: #metadata是该资源…