【后端面试总结】设计一个分布式锁需要思量哪些东西 ...

打印 上一主题 下一主题

主题 1029|帖子 1029|积分 3087

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分布式锁是我们在分布式场景中常常用到的一种技能,在后端面试中也是出镜率很高,那么我们设计分布式锁的时候应该从那几方面去思量呢
实现分布式锁需要思量的点

设置超时时间

设置超时时间的目的是为了制止这个场景:历程A拿了锁,但是在持有锁期间本身因为某些异常挂掉了,这样历程A就永久不会释放掉这个锁了。如果没有设置超时时间的话,这个锁就会死锁,所以会需要设置一个超时时间,来保证当锁的持有者无法释放锁的时候,锁不会成为死锁。
设置守护线程

设置守护线程的目的是为了制止这个场景:历程A拿了锁,也设置了超时时间30s,但是因为某些业务的缘故原由,历程A确实需要持有锁高出30s,那么这个时候如果不加任何干预的话30s后锁主动释放肯定是不符合预期的。
有些同学可能就会问了,那我不是把超时时间设置长一点就好吗?但是一是超时时间设置长了是会有副作用的,那就是锁持有者无法释放锁时锁主动持有的时间会变长;二是纵然设置的再长也是有个限定的,无法完全保证不会发生正常使用的锁被错误的主动释放掉。
所以我们需要在持有锁的这个历程中额外增加一个线程,具体做的事变就是当持有锁的时间高出锁逾期时间的一半时,主动对超时时间进行一个续期,这样当历程存在的时候,就会一直对超时时间进行续期,不会被不测的主动释放;如果历程挂掉的话,则不会进行续期,超时后锁会被主动释放,也不会产生死锁。
Redis实现分布式锁重要要注意的地方



  • 使用SETNX实现排他性锁,SETNX意为set if not exist,即如果这个锁已经被持有了,则无法再次申请
  • 使用超时限定特性来制止死锁
  • 释放锁的时候需要进行检查来制止误释放别的历程的锁:添加key的时候使用uuid生成一个identifier,作为key的value随key一同写入redis;释放的时候,使用get下令获取到锁的value的时候,检查是不是之前存的谁人identifier,如果不是的话就说明锁已经释放了
tooz实现基于redis的分布式锁的实现方法

获取到一个锁的实例以后,如果acquire乐成,则将acquired置为True
恣意一个锁的实例想要release锁的话,先判断acquired是否为True,如果为True才允许释放,如果为False直接抛出异常“不能释放没有获取的锁”,以此制止错误释放
超时时间过一半以后,实例会主动延长超时时间到原本设置的超时时间,制止因为超时时间的设置把原本需要很长时间处理的任务的锁错误的释放掉了
使用setnx和expire的问题:setnx和expire是两条指令而不是原子指令。
解决办法:使用set扩展参数替换:set key value ex 5 nx

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表