其他
面试时遇到「看门狗」脖子上挂着「时间轮」,我就问你怕不怕?
The following article is from why技术 Author why技术
你面试被问到,没有答上来,然后呢? 面试结束之后你没有进行面试的复盘吗? 对于自己没有回答上来的问题,没有去进行探索吗?
先看示例代码
value去哪里了? 过期时间去哪里了?
SET key random_value NX PX 3000
你给我讲一讲基于Redis的加锁和释放锁的细节吧。
原子命令加锁。 设置值的时候,放的是random_value。 value 的值设置为随机数主要是为了更安全的释放锁,释放锁的时候需要检查 key 是否存在,且 key 对应的值是否和我指定的值一样,是一样的才能释放锁。所以可以看到这里有获取、判断、删除三个操作,为了保障原子性,我们需要用 lua 脚本。
线程 A 在判断了 value 是自己放进去的,在执行 key 删除操作之前,程序 GC 导致了 STW。 STW 期间线程 A 的锁虽然没有执行删除操作,但是由于时间到期被 redis 释放了。 STW 之后,在线程 A 执行删除操作之前,线程 B 加了同样 key 的锁。 结果你猜怎么着?线程 A 把线程 B 加的锁删除了。这就出问题了。
org.redisson.RedissonLock#lock(long, java.util.concurrent.TimeUnit, boolean)
org.redisson.RedissonLock#tryLockInnerAsync
org.redisson.connection.ConnectionManager
org.redisson.RedissonLock#tryLockInnerAsync
script:是要执行的 lua 脚本。 keys:是 redis 中的 key。这里的 why 就是 KEYS[1]。 params:是 lua 脚本的参数。这里的 30000 就是 ARVG[1]。UUID:thredId 就是 ARVG[2]。
第一部分:加锁
org.redisson.RedissonLock#tryAcquireAsync
org.redisson.RedissonLock#scheduleExpirationRenewal
org.redisson.RedissonLock#renewExpiration
task,任务,对于 Redssion 看门狗功能来说,这个 task 就是把对应的 key 的过期时间重置,默认是 30s。 delay,每隔多久执行一次,对于 Redssion 看门狗功能来说,这个 delay 就是 internalLockLeaseTime/3 算出来的值,默认是 10s。 unit,时间单位。
https://www.jianshu.com/p/1eb1b7c67d63
https://www.ibm.com/developerworks/cn/linux/1308_liuming_linuxtime3/index.html
进入,然后加一,你联想到了什么? 这不就是可重入锁吗! 看到这里的时候,解锁的 lua 脚本都不必看的,想也能想到,肯定是有一个减一的操作,然后减到 0,就释放这把锁。一会我们就去验证这个点。
rLock.lock(5,TimeUnit.SECONDS);
图片来源: https://juejin.im/post/5bf3f15851882526a643e207
由于某种异常原因,导致你本次需要处理的数据比之前的多,所以,需要的时间更长,导致一直在进行续期操作。 你的代码有问题,导致了死循环,也就是死锁的出现,这个锅,Redssion 不背。
很用心的为你写了 9 道 MySQL 面试题,建议收藏! 小网站的容器化(下):网站容器化的各种姿势,先跟着撸一波代码再说! 克隆一个 AI 替自己开会,爽吗? 以太坊2.0中的Custody Game及MPC实现 程序员:“我放弃了年薪 20 万的 Offer” 20万个法人、百万条银行账户信息,正在暗网兜售