| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> redis实现分布式锁要点速通 -> 正文阅读 |
|
[大数据]redis实现分布式锁要点速通 |
目录 为什么要有分布式锁我们在单机时,有单机锁去解决线程操作共享资源安全的问题。安全问题意思就是线程操作结果和你预期结果不符合。 我们现在是分布式系统,会有多个进程操作一个共享资源的情况,所以也会出现安全问题。这个时候我们就需要一个外部系统去实现互斥的能力。所以引入了分布式锁。这次我们主要讲redis实现分布式锁原理以及注意事项。 实现原理我们利用redis的setnx指令去实现互斥能力。 这个指令意思是set if not exits。如果key不存在,才去设置,如果存在则不设置。 案例:test为key,第一次设置成功,第二次不成功。 我们用del命令去释放锁。 案例:?释放锁(删除key)之后,setnx命令成功。 ?类比到分布式锁:客户端A抢占test这个锁,抢占成功。客户端B,抢占test这个锁则失败。如果客户端A执行完之后要及时释放锁。 死锁的情况以及死锁怎么办死锁情况:如果客户端A抢占成功后执行逻辑出现异常(或是A服务挂了),没执行del操作,那锁就一直被占有,无法释放。其他客户端将无法拿到这个锁(无法setnx成功)。 解决办法:把锁设置过期时间。既然客户端A无法释放,我们就设定时间让他释放,到达时间key直接过期。 实例:设置key为test————设置过期时间10s————再次设置key为test ?分两步步设置key和过期时间的问题身为大聪明的你一眼就看出这是两步操作(1、设置key。2、设置过期时间)。有没有一种可能,我是说有没有一种可能设置完key之后,正在设置过期时间时程序挂了或是种种原因没执行。他们并不是原子操作,所以我们需要把设置key和过期时间变为原子操作。 案例:把设置key和过期时间变为原子操作。 ?业务执行时间超过锁过期时间描述?如果A抢到了锁并且设置过期时间为10s。但是A业务执行了20s。 也就是说: A执行完之前B拿到锁安全问题:锁过期了但是A仍在执行,这时B抢锁成功去执行自己的逻辑。这样仍会产生安全问题。 A执行完之后释放别人的锁:A本身有释放锁的操作,会错误的把B的锁给释放掉。 解决方案释放别人的锁我们在设置key的时候value设置为一个唯一值(如UUID或是其他) 在释放锁之前判断value是否是自己设置的之后再删除。如:
可是这样仍是两步操作:对比——删除。如果我们对比之后准备删除时B抢占到了锁,仍会出现误删情况。 所以我们仍然要一个原子操作。 这个时候我们就需要lua脚本了。让redis来执行,因为redis是单线程所以,知道脚本执行后才执行其他操作。 ?不好评估过期时间身为大聪明的你可能也想到了设置一个守护线程,监控业务运行和过期时间,如果快要过期了业务还在运行,则对之前设定的过期时间进行续签。这个守护线程专业术语叫做“看门狗”。 ?Java 技术栈中已经有一个库把这些工作都封装好了:Redisson。 一个线程抢到锁,其他线程在做什么线程A拿到锁后,线程B就一直通过io用setnx自旋拿锁。redisson实现自旋锁 如果有很多线程,就会造成很多线程自旋。 这个时候就要用到redis的订阅发布、阻塞队列。 (有待确定,有知道的小伙伴请补充) 集群redis中可能会出现的问题主从复制redis中 ?如果A去master加锁成功之后还没同步到slave,锁就消失了。新的master中就没有加锁了。 那如何去解决呢? 这时候就要引入我们常听的(或者压根没听过)Redis 作者提出一种解决方案——?Redlock红锁 Redlock前提
大概是这个样子去拿锁。 ?操作步骤?总结:
如果没有一半以上的则随机重试(会出现重试,直到出现返回一半以上的锁) 该算法对系统时钟做出了危险的假设(假设多个节点机器时钟都是一致的),如果不满足这些假设,锁就会失效。 分布式锁分为两大类1、类cas自旋,轮询询问。代表技术:redis、mysql 2、event事件通知。代表技术:zookeeper、etcd |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 14:41:47- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |