redis及实现分布式锁的原理

redisson分布式锁原理:

一部分逻辑是拿锁,如果key不存在则获取锁成功,为避免锁没有释放造成死锁默认leasetime(过期时间))30s,看门狗机制会定时判断线程存在就重新设置过期时间续期,以免锁错误释放被别人抢到。如果key存在会判断是不是本身已经加过锁,是的话增加锁重入次数。

即如果你指定了 leaseTime:Redisson 认为你要自己控制锁的时间,它只负责设锁,不负责续期。时间一到,锁直接释放,即使业务没跑完也可能发生并发问题(业务超时)。

如果你没指定 leaseTime (默认情况):Redisson 默认给你 30 秒的持有时间。一旦你成功抢到锁(ttlRemaining == null),Redisson 会立刻在后台启动一个看门狗线程。看门狗会不断给你"续期",防止你业务还在跑,锁却过期了被别人抢走。

另一部分是拿到锁之后的看门狗逻辑

延迟: 每次任务不会立即执行,而是等 10 秒(1/3 过期时间)。

执行: 到了时间,去 Redis 检查锁是否还存在并重置过期时间("看门")。这里是异步执行Lua脚本实现的

递归: 如果重置成功,就再次调用自己,安排下一次 10 秒后的检查。

并发安全: 使用 expirationRenewalMap 和 putIfAbsent 确保多线程环境下不会启动多个重复的定时任务。即每个锁一个看门狗任务。

Redisson 能够让锁在业务运行期间一直"活着",直到业务主动解锁的秘密。

这里的定时任务是用netty的HashedWheelTimer实现的,控制时间轮转动,将任务放到对应的轮次分片上,并执行当前时间轮的任务,类似循环队列,对时间取模,如果不是本轮次的则减一直到为0表示是当前轮次

另一部分逻辑是没有获取到锁时,如果有等待时间,会阻塞去再次拿锁,用semaphore实现,并且创建消息监听,当锁释放时会接收消息去重新获取锁。

补充:

redis做缓存

如果缓存里没有,去查数据库。为了避免全都打到数据库,加锁串行执行,保证一个线程去查,查到之后存缓存,剩下的都会继续从缓存里查,这里做了双重检查。

相关推荐
笨蛋不要掉眼泪1 小时前
RabbitMQ消息队列:MQ的可靠性
分布式·rabbitmq·java-rabbitmq
晚安code2 小时前
RocketMQ 顺序消费实战:批量接口加 Redis Pipeline同步数据
redis·rocketmq
西门啐血2 小时前
Vue 缓存之坑,变量赋值方式和响应式数据
前端·vue.js·缓存
qq_185198692 小时前
SpingBoot3入门学习一
学习
噗噗夹的TA之旅2 小时前
Shader 学习 21:自定义 Render Feature
学习·游戏·unity·c#·游戏引擎·图形渲染
Zane19942 小时前
CAS 与原子类:Java 如何实现无锁编程
java·后端
TunerT_TQ2 小时前
【智能体安全治理|专栏第9期】从“一堆规则”到“数字宪法”:智能体治理的下一个阶段
java·开发语言·安全·开源治理·大模型安全·ai基础设施·智能体安全
legendary_bruce2 小时前
RAG知识库进阶-1
java·aigc
必须会一定会2 小时前
大模型手搓文件对比工具(6):差异不用再手选
java·人工智能·ai编程
yio_yin3 小时前
MyBatis
java·前端·mybatis