欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

redis实现分布式锁(乞丐版)

发布时间:2023/12/16 编程问答 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 redis实现分布式锁(乞丐版) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

文章目录

    • redis分布式锁
      • 分布式锁
        • 加锁
        • 解锁

redis分布式锁

今天记录一下redis实现分布式锁,写这个话题我犹豫了很久,因为这个实现虽然很容易,但是有很多细节需要注意,一不小心就死锁,但是仔细一想好像也没几个人看我的文章,就当给自己做个笔记吧!大佬们要是发现那儿思路有问题,期待你能指出来哦,在生产环境下最好用redisson,别傻傻的自己实现了

在单机下我们的多线程争抢资源是很好解决的,无非就是加锁,Reentrantlock,synchronized等等都行,但是在多线程的情况下,他们已经不是同一个JVM了,他们是不可能在自己的JVM锁到同一个对象的,如图:

所以,在分布式系统中我们需要的是这样一个架构:

这儿的中间件我们今天就是用的redis,后面可能会再写一下zookeeper实现分布式锁

我们只需要知道的几个很简单的redis命令:

set 示例: set name xiaoZ EX 5 NX 解释: 设置name字段的值为xiaoZ,失效时间为5秒,如果不存在这个key的话

expire 示例: expire name 5 解释: 设置name字段的超时时间为5秒

del 示例: del name 解释: 删除name字段

分布式锁

假设现在两台机器一共8个线程都在争抢锁

加锁

那么他们怎么才能算抢到锁呢?

redis发挥作用了,set加上NX参数能保证只有一次set操作能成功,为什么呢?我们暂且可以将redis理解为单线程,所以进来的8个操作是排好队的,听大佬们说好像redis并不完全都是单线程,这儿等我了解后再记录吧。(小本本记上)

set lock 只有自己知道的一个值,可以是随机数 EX 5 NX

既然只有一个操作能成功的话,那不就不用担心资源争抢的问题了,不就实现了分布式加锁了吗?

网上很多方案是用setnx加expire,其实这儿会有一点问题,因为他不是原子性的,如果在setnx之后刚好宕机了,那么这个锁就没有失效时间了,造成死锁,当然,这儿可以用lua脚本操作,lua脚本是具备原子性的

解锁

解锁直接使用del将lock这个键删除不就解锁了吗,不过要注意的是,我们需要判断一下这个锁是不是自己的,怎么判度就是去对比value,这个value只有自己知道,如果一样就删除,那么需要先判断一下,那么又出现了原子问题,这儿我们可以使用lua脚本实现,因为之前说过lua脚本是具备原子性的

if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) elsereturn 0 end

总结

以上是生活随笔为你收集整理的redis实现分布式锁(乞丐版)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。