如果你连redis分布式锁都不懂,对不起,你只能拿2k了,懂了他,你能拿3k

計贰-CSDN博客

看这个文章,写的很好,关于setnx。

redis里面有个命令叫做setnx,如果有key存在,就不成功,如果key不存在,就成功,并设置值。

没有这个key的话,就返回1,并且设置为值。有的话,就返回0,不操作。

获取锁就用setnx,释放锁的话,就把它删了就行,这东西有点像mysql基于主键实现分布式锁。

但是如果线程在释放锁之前就挂了,这个锁就不能被释放,就会造成死锁。(这里可能有点懵,按照正常来说,你业务执行完,手动把key删了就行了。但是万一你在还没有到手动删key的时候,挂了,那咋办)

那我们怎么办,定个过期时间删除rediskey就行了,免得它一直死锁,所以我们又要加上expire

网络波动或者业务逻辑太复杂的原因,5s时间到了,但是业务逻辑没执行完(这又是什么情况,就仿佛你上网,你游戏还没有打完,但是网费用完了到期,麻的,怎么把我电脑关了。)

另外一个人抢到锁,上一个没有执行完业务逻辑的搞完了,执行删除key操作,哦,直接完蛋。

所以又要用到看门狗机制,判断下业务执行完没有,没有执行完,给它延时。本质就是个定时任务,当某个线程获得锁,在线程中搞个定时任务,每三秒钟,看它执行完没有。没有,就延长。

万一因为网络波动,看门狗没来得及,比如主人快死了,你在跑的路上,主人已经嗝屁了,没来及。又遇到,另外一个倒霉蛋拿到锁,上一个业务逻辑执行完,直接把key删了(线程b还没有执行完,连key都没有了),又完蛋。

设置key和value的时候,不能随便设置了,搞个uuid作为值存储。释放锁的时候,判断下uuid等于等于。(根据key获取 value,再判断value==uuid),最终释放锁。

根据key获取value,判断value==uuid,等于才删除key(要保证原子性)比如刚刚拿到key的值,另外一个倒霉蛋又来了,设置新的key和value。(这里有点没懂,反正意思就是不要被下一个进程影响到,不要磨磨唧唧,一个个执行语句,干脆直接全执行了!)

其实我这里我没怎么理解到,为什么要原子性,setnx不是没有才设置值,你根据key去拿value说key还在呀,别人怎么会拿得到key。除非是你刚拿到key,redis的key的时间到了过期,这个时候倒霉蛋又来了,设置新的key?反正这里没理解到。主要意思就是上个线程不能被下一个线程所影响,如果有懂的,可以评论区告诉下我。

反正这三个操作要同时进行,不能一步一步来,所以要用lua脚本。用了lua脚本,就是一荣俱荣,别人插不进来了。

所以当面试官问你关于redis分布式锁的原理,你就说,redis分布式锁是基于setnx和expire语句,加上看门狗机制,加上在value值上设置uuid,避免误删锁,最好加上lua脚本。(我觉得已经够了,谁有事没事问你那么多原理干嘛!)

但是在实际开发中,你直接用redission框架就行了,但是它的原理就是上面的逻辑

兄弟们,点了点关注,满足下作者虚荣心,作者都是没钱赚的,为爱发电的。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值