redis面试(十六)公平锁释放和排队加锁

锁释放

RedissonFairLock.unlockInnerAsync()方法

这和加锁的逻辑没有太大区别

也就是说在客户端A他释放锁的时候,也会走while true的脚本逻辑,看一下有序集合中的元素的timeout时间如果小于了当前时间,就认为他的那个排队就过期了,就删除他,让他后面重新尝试获取锁的时候重排序

while true的逻辑,比如说客户端B或者客户端C,他们用的是tryAcquire()方法,他们其实设置了一个获取锁超时的时间,比如说他们在队列里排队,但是尝试获取锁超过了20秒,人家就不再尝试获取锁了

此时他们还是在队列和有序集合里占了一个坑位,while true的逻辑就可以保证说剔除掉这种不再尝试获取锁的客户端,有序集合里的timeout分数就不会刷新了,随着时间的推移,肯定就会剔除掉他

如果客户端宕机了,也会导致他就不会重新尝试来获取锁,也就不会刷新有序集合中的timeout分数,不会延长timeout分数,while true的逻辑也可以剔除掉这种宕机的客户端在队列里的占用

因为网络延迟等各种因素在里面,可能会在等待锁时间过长的时候,触发各个客户端的排队的顺序的重排序,有的客户端如果在队列里等待时间过长了,那么其实是可以触发一次队列的重排序的

他在这里发布一个锁被释放的消息,肯定在他的源码中是有一些人是订阅了这个释放锁的消息的,此时他们就可以得到一个锁被释放掉的通知

排队加锁

如果客户端A释放了锁,删除了锁key之后,客户端B和客户端C是如何按照顺序依次加锁的。

要记得,刚才我们经历了队列重拍,排在队头的是客户端C,后面是客户端B

假设锁被释放掉了之后,如果客户端B先来尝试加锁

客户端B加锁失败

10:00:40,锁已经被释放了,客户端B来尝试重新加锁

10:01:04 <= 10:00:40?不成立

exists anyLock = 0,当前锁不存在;exists redisson_lock_queue:{anyLock} = 0,要不然就是队列不存在,但是现在队列是存在的;lindex redisson_lock_queue:{anyLock} 0 = UUID_02:threadId_02,队列存在,但是排在队列头部的不是客户端B的线程

所以上面整体条件不成立,无法加锁

ttl = 10:01:04 - 10:00:40 = 24000毫秒

timeout = 24000 + 10:00:40 + 5000 = 10:01:09

zadd指令,刷新一下客户端B在有序集合中的timeout分数,10:01:09

哪怕是锁释放掉了,其他各个客户端来尝试重新加锁也是不行的,因为此时排在队头的不是这个客户端也不行,此时只会重新计算timeout分数刷新一下有序集合中的timeout分数罢了

客户端C加锁成功

此时客户端C来尝试加锁会如何?

anyLock锁key不存在的;队列是存在的;队列的队头就是客户端C,所以此时加锁的条件成立了,进入加锁的逻辑

lpop redisson_lock_queue:{anyLock},将队列中的第一个元素弹出来

zrem redisson_lock_timeout:{anyLock} UUID_03:threadId_03,将有序集合中的客户端C的线程id的元素给删除掉

hset anyLock UUID_03:threadId_03 1,加锁

pexpire anyLock 30000,设置生存时间为30000毫秒

完成加锁,而且客户端C从队列中出队,此时排在队头的就是客户端B了

获取锁超时,其他客户端获取不到锁,一定会在java代码里进入一个while true死循环,一定时间内没有获取到锁,就返回false标识获取锁失败,过了一段时间,只要没有刷新有序集合中的timeout分数,就会自然被lua脚本里的while true逻辑给清理掉

超时自动释放锁,不会开启lock watchdog后台定时调度的任务

相关推荐
玄同7657 分钟前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
吾日三省吾码8 分钟前
别只会“加索引”了!这 3 个 PostgreSQL 反常识优化,能把性能和成本一起打下来
数据库·postgresql
chian-ocean10 分钟前
百万级图文检索实战:`ops-transformer` + 向量数据库构建语义搜索引擎
数据库·搜索引擎·transformer
小Tomkk29 分钟前
数据库 变更和版本控制管理工具 --Bytebase 安装部署(linux 安装篇)
linux·运维·数据库·ci/cd·bytebase
Serene_Dream1 小时前
JVM 并发 GC - 三色标记
jvm·面试
qq_12498707531 小时前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
倒流时光三十年1 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
forestsea2 小时前
深入理解Redisson RLocalCachedMap:本地缓存过期策略全解析
redis·缓存·redisson
码农小卡拉2 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
佛祖让我来巡山2 小时前
Redis 为什么这么快?——「极速快递站」的故事
redis·redis为什么快?