分布式锁的一些细节问题,值得收藏
原文
我看在技术大群里面有人问分布式锁问题,说是被面试官各种刁难,我是实在看不下去了,面试官意思很明确,你们有造火箭的经验吗,有的话来他们公司造自行车,没有的话:今天面试就到这里了!
但是说实话面试官没必要因为这个问题继续追问,没啥意思,但是又不得不问,确实有些企业用到分布式锁了。
没办法,逼迫你必须得背会它。
接下来就说下群友面试碰到的问题,因为候选人可能自己已经掌握了实现分布式锁的原理,但是被面试官问到细节可能就不清楚了,因此给大家讲下这块。
问题-1 如果setnx执行成功,但是在expire执行的时候redis节点宕机了,在这种情况下,锁不会被释放,导致死锁。解决方案:
问题-2 如果expire时间过短,但是任务执行时间过长,那么锁会因为过期而被删除,其它客户端可以重新获取锁。在这种情况下,多个客户端同时获取到了锁。解决方案:
问题-3 如果expire刚好过期,此时删除了这个key,那么当另一个客户端进行获取锁的时候就会抢到锁,那么这个时候当前释放锁的客户端会执行最后的del命令把别的客户端刚才设置的删除了,这个时候就破坏了资源的并发操作。
解决方案:
<pre data-tool="mdnice编辑器" style="box-sizing: border-box !important; margin: 10px auto 1rem; padding: 0px; outline: 0px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 12.25px; overflow: auto; display: block; color: rgb(33, 37, 41); max-width: 100%; overflow-wrap: break-word !important; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; border-radius: 4px;">`1. uuid = gen()
问题-4 假如redis主节点宕机,主从同步延迟或者有问题,那么从成为主之后,客户端就会重新获取到锁,这样也会并发不安全。解决方案:
问题-5 如果redis发生脑裂,那么也会发生多个客户端并发持有多个锁的问题,所以redis为了解决这个脑裂问题,引入两个配置,只有合理配置这两个参数就可以尽最大努力避免脑裂,细节大家下去自行研究哈。
只要线程成功获取到锁,就会启动一个watch dog,它是一个后台线程,每10秒检查一次,如果线程一持有锁,那么它会不断延长锁的生存时间。因此,Redisson是可以解决过期时间到了但是业务还没执行完的问题。
Redlock核心思想是这样的:部署多个redis master节点,确保它们不会同时宕机。而且这些主节点之间是完全独立的,它们之间没有数据同步。同时,我们需要确保使用相同的方法来获取和释放锁。具体获取锁和释放锁的步骤大家下去自行研究。
2024-11-22 广告