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]) 
else
   return 0 
end
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值