Redis锁分析

基于Redis的锁一般分单节点或集群多节点二中情况,下面分别介绍一下。

Redis单节点(客户端:Jedis)

一、正确的加锁方式

jedis.set(String key, String value, String nxxx, String expx, int time)

第一个参数为:key

第二个参数为:值(一般为一个随机数,这也是有讲究的,知道为什么?)

第三个参数为:设置为NX,代表key不存在操作,存在的情况下不处理返回,从而确保只有一个客户端可以获得锁;

第四个参数为:设置为PX 用于标识指定超时时间

第五个参数为:超时时间,单位:毫秒(为什么要指定超时时间?......要是我挂了,不能执行删除命名,那是不是锁就不释放了!!)

注意:这里为什么不用setNx呢?jedis的setnx不能把设置值和指定过期时间放在一起执行,即非原子性,有风险呀。

二、释放锁

String lua_script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(lua_script, Collections.singletonList(key), Collections.singletonList(获取锁时生成的随机数));

if (RELEASE_SUCCESS.equals(result)) {
	return true;
}

1、Redis支持直接运行Lua脚本语言,更多lua见 https://www.runoob.com/lua/lua-tutorial.html

2、为什么不通过get--del等命令来处理呢?---> 因为Lua可以确保原子性,这个命令在一个事务端中

 

既然是单节点,那对可用性就做不到保障了,集群在这时就诞生了,那对于在集群环境下分布式锁要注意什么呢?

Redis官方推出了RedLock,我们对它认识一下

RedLock是通过同一个key和value,在种master节点上申请锁,当在超过一半的节点上获取时,即代表该进程成功获取到了锁。 

大致实现如下(假设这里有5个redis master,锁自动释放时间(TTL)为10秒):
1、开始获取锁量首先获取当前时间戳;

2、客户端进程用相同的key,value去所有的redis master 服务中获取锁,获取锁会设置一个超时时间(超时时间远小于【锁自动释放时间】,防止master节点阻塞过长时间引起系统性风险),当超过获取时间时,直接去下一个节点获取锁;

3、客户端获得所有可获得的锁的时间减去第一步记录的时间戳,小于TTL且至少在3个master上成功获取锁,才是真正的锁成功;

4、若获取锁成功,则锁的真正有效时间为TTL减去(之前获取锁总消耗时间+系统时间波动);

5、如果客户端获取锁失败,在所有的结点上进行锁释放,否则会影响其它客户端获取锁。释放锁时需判断这个锁的value是不是自己设置的,如果是才删除。

 

 

RedLock性能及崩溃恢复的相关解决方法

1.如果redis没有持久化功能,在clientA获取锁成功后,所有redis重启,另一客户端能够再次获取到锁,这样违法了锁的排他互斥性;

2.如果启动AOF永久化存储,事情会好些, 举例:当我们重启redis后,由于redis过期机制是按照unix时间戳走的,所以在重启后,然后会按照规定的时间过期,不影响业务;但是由于AOF同步到磁盘的方式默认是每秒-次,如果在一秒内断电,会导致数据丢失,立即重启会造成锁互斥性失效;但如果同步磁盘方式使用Always(每一个写命令都同步到硬盘)造成性能急剧下降;所以在锁完全有效性和性能方面要有所取舍; 

3.有效解决既保证锁完全有效性及性能高效及即使断电情况的方法是redis同步到磁盘方式保持默认的每秒,在redis无论因为什么原因停掉后要等待TTL时间后再重启(学名:延迟重启) ;缺点是 在TTL时间内服务相当于暂停状态;

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值