作为一个面试官,我想问问你Redis分布式锁怎么搞…
2020-06-10 16:02:30来源:博客园 阅读 ()
作为一个面试官,我想问问你Redis分布式锁怎么搞?
总结一下加锁过程:首先选择一台机器,然后发送一段lua脚本,带有三个参数:一个是锁的名字(在代码里指定的)、一个是锁的时常(默认30秒)、一个是加锁的客户端id(每个客户端对应一个id)。然后脚本会判断是否有该名字的锁,如果没有就往数据结构中加入该锁的客户端id。 最强面试题推荐:2020Java面试题及答案,命中率高达90%
总结一下加锁过程:首先选择一台机器,然后发送一段lua脚本,带有三个参数:一个是锁的名字(在代码里指定的)、一个是锁的时常(默认30秒)、一个是加锁的客户端id(每个客户端对应一个id)。然后脚本会判断是否有该名字的锁,如果没有就往数据结构中加入该锁的客户端id。
锁互斥机制
很简单,上面第一个if判断会执行“exists myLock”,如果发现myLock这个锁key已经存在了,就会进行第二个if判断,判断一下myLock锁key的hash数据结构中,是否包含客户端2的ID,但是明显不是的,因为那里包含的是客户端1的ID。
所以,客户端2会获取到pttl myLock返回的一个数字,这个数字代表了myLock这个锁key的剩余生存时间。比如还剩15000毫秒的生存时间。
此时客户端2会进入一个while循环,不停的尝试加锁。直到客户端1释放myLock这个锁。
锁时间自动延迟机制
客户端1加锁的默认时长是30秒,如果超过了30秒,客户端1还想持有这把锁该怎么办呢?机制如下:
只要客户端1一旦加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端1还持有锁key,那么就会不断的延长锁key的生存时间。
可重入加锁机制
如果客户端1已经持有这把锁了,还想加锁,该怎么办呢?比如代码逻辑如下:
Rlock lock = redisson.getLock(“myLock”); lock.lock(); // 一坨代码 lock.lock(); // 一坨代码 lock.unlock(); lock.unlock();
这时我们来分析一下上面那段lua脚本。第一个if判断肯定不成立,“exists myLock”会显示锁key已经存在了。第二个if判断会成立,因为myLock的hash数据结构中包含的那个ID,就是客户端1的那个ID,也就是“
8743c9c0-0795-4907-87fd-6c719a6b4586:1”
此时就会执行可重入加锁的逻辑,他会用:incrby myLock
8743c9c0-0795-4907-87fd-6c71a6b4586:1 1 通过这个命令,对客户端1的加锁次数,累加1。
此时,myLock的数据结构变成了这样:
myLock: { “8743c9c0-0795-4907-87fd-6c719a6b4586:1”:2 }
可以看出,后面那个数字表示该id的锁的加锁次数。
锁释放机制
如果执行lock.unlock(),就可以释放分布式锁,此时的业务逻辑也是非常简单的。其实说白了,就是每次都对myLock数据结构中的那个加锁次数减1。如果发现加锁次数是0了,说明这个客户端已经不再持有锁了,此时就会用:“del myLock”命令,从redis里删除这个key。然后呢,另外的客户端2就可以尝试完成加锁了。
这就是Redis分布式锁基于开源Redisson框架的实现机制。
Redis分布式锁的缺点
这种分布式锁最大的缺点在于:如果对某个redis-master实例写入了myLock这个key的锁的value,此时会异步复制数据到redis-slave实例上。
但是在这个过程中发生了redis-master宕机了,主备切换,redis-slave变成了redis-master。
紧接着,客户端2就来尝试加锁,在新的redis-master上加了锁,而此时客户端1也认为自己加了锁,这就导致多个客户端对同一个分布式锁完成了加锁。
原文链接:https://www.cnblogs.com/yuxiang1/p/13086677.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- JVM常见面试题解析 2020-06-11
- 送你一份年薪百万的抖音Java岗内部面试题 2020-06-09
- 一口气说出 6种 延时队列的实现方案,面试稳稳的 2020-06-08
- 面试的时候按照这个套路回答 Java GC 的相关问题一定能过 2020-06-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash