在这个技术不断更新迭代的情况下,分布式这个概念,在企业中的权重越来越高!谈及分布式时,不可避免一定会提到分布式锁,现阶段分布式锁的实现方式主流的有三种实现方式, zookeeper、db、redis,我们本篇文章以redis为例!
从我们的角度来看,这三个属性是有效使用分布式锁所需的最低保证。
安全特性:互斥。在任何给定时刻,只有一个客户端可以持有锁。
活力属性:无死锁。最终,即使锁定资源的客户端崩溃或分区,也始终可以获得锁。
活动性:容错能力。只要大多数Redis节点都处于运行状态,客户端就可以获取和释放锁。
我们使用Redis锁定资源的最简单方法是:
在实例中创建锁。
锁通常使用Redis过期功能在有限时间存在,因此最终将被释放,最终超过给定期限会被删除。
当客户端需要释放资源时,它将删除锁。
乍一看,似乎并没有什么问题。但是不妨我们深究一下,这种实现方案在redis单机环境下似乎并没有什么问题!但是如果节点宕了呢?好吧,那么让我们添加一个sl*e节点!如果主服务器宕机了,就使用这个节点!但是我们不妨来看看她真的能保证可用吗?
在谈论这个的致命缺陷时,我们需要了解一个知识点,Redis复制是异步的。
客户端A获取主服务器中的锁。
在将锁复制传输到从机之前,主机崩溃。
sl*e晋升为
master。
客户端B获取锁,因为从机并没有该锁的对象,获取成功!
显然,这样是不对的,主节点因为没来得及同步数据就宕机了,所以从节点没有该数据,从而造成分布式锁的失效,那么作者antirez的观点是如何解决这个呢?
作者认为,我们应该使用多个Redis,这些节点是完全独立的,不需要使用复制或者任何协调数据的系统,多个redis系统获取锁的过程就变成了如下步骤:
以毫秒为单位获取当前的服务器时间
尝试使用相同的key和随机值来获取锁,对每一个机器获取锁时都应该有一个超时时间,比如锁的过期时间为10s那么获取单个节点锁的超时时间就应该为5到50毫秒左右,他这样做的目的是为了保证客户端与故障的机器连接,耗费多余的时间!超时间时间内未获取数据就放弃该节点,从而去下一个节点获取,直至将所有节点全部获取一遍!
获取完成后,获取当前时间减去步骤一获取的时间,当且仅当客户端半数以上获取成功且获取锁的时间小于锁额超时时间,则证明该锁生效!
获取锁之后,锁的超时时间等于
设置的有效时间-获取锁花费的时间
如果 获取锁的机器不满足半数以上,或者锁的超时时间计算完毕后为负数 等异常操作,则系统会尝试解锁所有实例,即使有些实例没有获取锁成功,依旧会被尝试解锁!
释放锁,只需在所有实例中释放锁,无论客户端是否认为它能够成功锁定给定的实例。
Martin Kleppmann发表文章任务,Redlock并不能保证该锁的安全性!
他认为锁的用途无非两种
提升效率,用锁来保证一个任务没有必要被执行两次。比如(很昂贵的计算)
为确保准确性,使用锁机制以确保任务按照正常流程顺序进行,以避免两个节点同时对同一份数据进行操作,导致文件冲突和数据丢失。
对于第一种原因,我们对锁是有一定宽容度的,就算发生了两个节点同时工作,对系统的影响也仅仅是多付出了一些计算的成本,没什么额外的影响。这个时候 使用单点的 Redis 就能很好的解决问题,没有必要使用RedLock,维护那么多的Redis实例,提升系统的维护成本。
WiseHome家政预约小程序
家政服务平台系统包含家用电器安装清洗、搬家、家电维修、管道疏通、月嫂保姆、育儿陪护、*开锁等多种服务项目,用户可以直接通过家政小程序咨询,在线预约服务类型,同时还设置有知识科普,给用户科普一些清洁保养小技巧,让用户能够足不出户就可以直接预约服务,方便又快捷。本项目使用微信小程序平台进行开发。使用腾讯专门的小程序云开发技术,云资源包含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需
0
查看详情
但是对于第二种场景来说,就比较慎重了,因为很可能涉及到一些金钱交易,如果锁定失败,并且两个节点同时处理同一数据,则结果将导致文件损坏,数据丢失,永久性不一致,或者金钱方面的损失!
我们假设一种场景,我们有两个客户端,每一个客户端必须拿到锁之后才能去保存数据到数据库,我们使用RedLock算法实现会出现什么问题呢?RedLock中,为了防止死锁,锁是具有过期时间的,但是Martin 认为这是不安全的!该流程图类似于这样!
客户端1获取到锁成功后,开始执行,执行到一半系统发生Full GC ,系统服务被挂起,过段时间锁超时了。
客户端2等待客户端1的锁超时后,成功的获取到锁,开始执行入库操作,完成后,客户端1完成了Full GC,又做了一次入库操作!这是不安全的!如何解决呢?
Martin 提出来一种类似乐观锁的实现机制,示例图如下:
客户端1长时间被挂起后,客户端2获取到锁,开始写库操作,同时携带令牌 34,写库完成后,客户端1苏醒,开始进行入库操作,但是因为携带的令牌为33 小于最新令牌,该次提交就被拒绝!
即使系统出现问题导致挂起,该思路似乎完备,可确保数据仍能得到正确处理。但是仔细想一下:
如果仅当您的令牌大于所有过去的令牌时,数据存储区才能始终接受写入,则它是可线性化的存储区,相当与使用数据库来实现一个 分布式锁系统,那么RedLock的作用就变的微乎其微!甚至不在需要使用redis保证分布式锁!
回想一下Redlock算法获取锁的几个步骤,你会发现锁的有效性是与当前的系统时钟强依赖,我们假设:
我们有,A B C D E 五个redis节点:
客户端1获取节点A,B,C的锁定。由于网络问题,无法访问D和E。
节点C上的时钟向前跳,导致锁过期。
客户端2获取节点C,D,E的锁定。由于网络问题,无法访问A和B。
现在,客户1和2都认为他们持有该锁。
如果C在将锁持久保存到磁盘之前崩溃并立即重新启动,则可能会发生类似的问题。
Martin认为系统时间的阶跃主要来自两个方面(以及作者给出的解决方案):
人为修改。
对于人为修改,能说啥呢?人要搞破坏没办法避免。
从NTP服务收到了一个跳跃时时钟更新。
需要运维人员处理NTP接受阶跃时钟更新的问题。需要将阶跃的时间更新到服务器的时候,应当采取小步快跑的方式。多次修改,每次更新时间尽量小。
我们回顾 1 观点,深究抽象出现这个缺陷的根本原因,就是为了解决由于系统宕机带来的锁失效而给锁强加了一个失效时间,异常情况下,程序(业务)执行的时间大于锁失效时间从而造成的一系列的问题,我们能否从这方面去考虑,从而用程序来解决这个样一个死局 呢?
我们可以保证业务程序执行时间绝对小于锁超时时间,这样就可以避免锁失效时间小于业务时间的问题
j*a语言中redisson实现了一种保证锁失效时间绝对大于业务程序执行时间的机制。官方叫做看门狗机制(Watchdog),他的主要原理是,在程序成功获取锁之后,会fork一条子线程去不断的给该锁续期,直至该锁释放为止!他的原理图大概如下所示:
redisson使用守护线程来进行锁的续期,(守护线程的作用:当主线程销毁,会和主线程一起销毁。)防止程序宕机后,线程依旧不断续命,造成死锁!
另外,Redisson还实现并且优化了 RedLock算法、公平锁、可重入锁、连锁等操作,使Redis分布式锁的实现方式更加简便高效!
以上就是怎么使用Redis锁定资源的详细内容,更多请关注其它相关文章!
# 执行时间
# seo网站甄选20火星
# 南京网站建设高端
# 泰安专业网站优化
# 网站优化推广如何收费
# asp的网页对seo
# 开封优化网站建设
# 莱芜seo关键词优化
# 上犹机械公司网络营销推广
# 东莞推广营销多少钱
# seo郑州培训学校
# redis
# 挂起
# 多个
# 什么问题
# 这是
# 解决问题
# 令牌
# 死锁
# 编辑器
# 客户端
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
Safari浏览器自动填表功能失效怎么办 Safari表单管理修复
Python定时发送QQ消息
《东方财富》条件单关闭方法
批改网网页版登录 批改网电脑版学生登录入口
Retrofit根路径POST请求:@POST("/") 的应用与解析
PPT智能排版生成入口 免费PPT内容自动生成平台
使用TinyButStrong生成HTML并结合Dompdf创建PDF教程
如何在CSS中使用伪类:valid实现表单验证提示_结合:valid改变边框颜色
邦丰播放器频道搜索设置
无人机考证官网 中国民航无人机考证官网登录入口
win11怎么更改账户类型 Win11标准用户和管理员权限切换【教程】
照片整理的黄金法则是怎样的? 理解“收集-筛选-归档-备份”四步流程
《大学搜题酱》官网地址登录
c++如何实现一个简单的RPC框架_c++远程过程调用原理与实践
学习通网页版课程打不开_课程无法访问时的解决方法
Composer reinstall命令重装损坏的包
Sublime怎么自动添加CSS前缀_Sublime安装Autoprefixer插件
Win10运行窗口在哪里打开 Win10调出运行命令框快捷键【技巧】
C#解析并修改XML后保存 如何确保格式与编码的正确性
作业帮网页版不用下载入口 在线问老师快速答疑
如何高效地基于键列值映射DataFrame中的多个列
抖音火山版注销账号抖音会注销吗 抖音火山版与抖音账号注销关系
CSS绝对定位与溢出控制:实现背景元素局部显示不触发滚动条
谷歌邮箱官方入口链接 谷歌邮箱网页版电脑端快速登录
网易云音乐闹钟铃声设置教程
微信注销后银行卡解绑了吗_微信注销后银行卡解绑状态
《友玩*》创建群聊方法
《飞猪旅行》购买汽车票方法
j*a中赋值运算符是什么?
Win11怎么录屏_Windows 11自带Xbox Game Bar录制视频
sublime如何撤销关闭的标签页_sublime重新打开已关闭文件技巧
Vue 3中独立响应式实例的创建与应用
百度输入法在AutoCAD中无法输入中文怎么办_百度输入法CAD输入异常解决方法
J*aScript 数值去小数位处理:多种方法与实践
使用 J*aScript 随机化 CSS Grid 布局中的元素顺序
国际经济与贸易就业方向解析
PHP使用DOMDocument与XPath精准追加XML元素教程
《海豚家》注销账号方法
德邦快递查询入口登录官网 德邦快递单号查询系统入口
VS Code快捷键when上下文子句的妙用
CSS动画如何实现图标旋转并放大_transform rotate scale @keyframes实现
知乎APP怎么查看自己被邀请的问题_知乎APP邀请回答记录查看与参与方法
研招网官方网站招生平台入口_中国研究生招生信息网官网登录
qq音乐官方网站入口_qq音乐在线听歌网页版链接
微信网页版在线登录 微信网页版在线使用入口
Lar*el Eloquent中通过Join查询关联数据表:解决多行子查询问题
CSS过渡与滚动滚动事件结合应用_scroll与transition动画
视频号视频怎么免费保存到相册?保存到相册需要注意什么?
TikTok视频播放中断怎么办 TikTok播放异常修复方法
edge浏览器怎么修改语言为中文_Edge界面语言切换教程
2023-05-28
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。