Redis 分布式锁

现在很多公司都喜欢用Redis做分布式锁。
来讲一讲Redis锁的概念

1.SETNX

最早都是用SETNX 来做分布式锁
Setnx命令在指定的 key 不存在时,为 key 设置指定的值
对比SET
举2个例子:
set(“boss”,“you”);
set(“boss”,“me”);
这里执行完后boss的值是 me;


setNx(“boss”,“you”);
setNx(“boss”,“me”);
执行完后 boss的值是 you

因为setNx只有key 不存在的时候才会执行
所以被用来做分布式锁。只有一个线程能够执行,其余的要等这个线程删除该key 后才能继续执行。

Jedis中的写法

Long result = jedis.setnx(key, value);
返回值result :设置成功,返回 1 。设置失败,返回 0
这个就是分布式锁的简单应用

当然会出问题:
1.如果是在并发情况下线程A 已经取得锁,但是执行中挂掉了,它无法再释放锁。其他线程就永远也强不到锁。
针对这个情况可以加finally{}

2.如果在并发情况下线程A 已经取得锁,但是执行过程中整个机器挂了。finally{}都无法再执行(死锁)
这个时候就需要加超时时间了,给锁一个失效时间,到时间后立即删除

3.如果线程A执行的时间比较长,长过你设置的超时时间。那在A还是执行的时候就已经因为超时删除了锁,这个时候B线程启动抢到锁,同时A线程执行完,把B线程的锁删除。
原因就是删除其他线程的锁,这时需要设置一个ID ,删除锁前先判断是否是当前线程的ID ,如果是再删除。
如何控制锁不失效?
如果设置的锁过期时间是固定的,可能会出现执行时间过长,超过过期时间被误删。
如果不想被误删就需要设置一个动态的过期时间:
抢到锁后,启动一个其他线程来监控当前线程执行状态,每隔一定时间重置一下过期时间,只要线程还再运行就一定不会超时。

Redission 中的写法

Redisson为Java上的分布式应用程序提供了基于Redis的对象,集合,锁,同步器和服务的 分布式实现

Rlock lock = redission.getLock(“mylock”);// 获取锁
lock.lock();// 加锁
lock.unlock();// 删除锁

Redisson 简单的几句已经为你把上面提到过的问题都解决了。

但是Redission 也有自己的问题,redis主从复制时如果出现数据不一致
eg:
redis master宕机,主备切换,redis slave变为了redis master。
接着就会导致,客户端2来尝试加锁的时候,在新的redis master上完成了加锁,而客户端1也以为自己成功加了锁。
此时就会导致多个客户端对一个分布式锁完成了加锁。
这时系统在业务语义上一定会出现问题,导致各种脏数据的产生。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值