分布式锁超时问题的处理(只是参考,推荐使用redission框架和ZK做分布式锁)

该博客探讨了Redis分布式锁在超时、主从切换等场景下可能导致的问题。主要内容包括:1) Redis分布式锁的基本实现,通过SETNX命令确保唯一性;2) 解决业务逻辑执行超时导致的并发问题,通过Lua脚本延长锁超时时间;3) 主从切换时的锁安全问题,以及在业务场景中发现和解决分布式锁偶尔失效的情况。建议使用Redission框架和ZK进行分布式锁管理。
摘要由CSDN通过智能技术生成

1、redis分布式锁的基本实现

redis加锁命令:

SETNX resource_name my_random_value PX 30000 

这个命令的作用是在只有这个key不存在的时候才会设置这个key的值(NX选项的作用),超时时间设为30000毫秒(PX选项的作用) 这个key的值设为“my_random_value”。这个值必须在所有获取锁请求的客户端里保持唯一。

SETNX 值保持唯一的是为了确保安全的释放锁,避免误删其他客户端得到的锁。举个例子,一个客户端拿到了锁,被某个操作阻塞了很长时间,过了超时时间后自动释放了这个锁,然后这个客户端之后又尝试删除这个其实已经被其他客户端拿到的锁。所以单纯的用DEL指令有可能造成一个客户端删除了其他客户端的锁,通过校验这个值保证每个客户端都用一个随机字符串’签名’了,这样每个锁就只能被获得锁的客户端删除了。

既然释放锁时既需要校验这个值又需要删除锁,那么就需要保证原子性,redis支持原子地执行一个lua脚本,所以我们通过lua脚本实现原子操作。代码如下:

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

2、业务逻辑执行时间超出锁的超时限制导致两个客户端同时执行(而不是叫同时获取锁的错误写法)的问题

如果在加锁和释放锁之间的逻辑执行得太长,以至于超出了锁的超时限制,就会出现问题。因为这时候第一个线程持有的锁过期了,临界区的逻辑还没有执行完,(疑问:锁超时了,是不是释放锁呢,既然释放锁了,怎么是二个线程都持有这把锁呢),这个时候第二个线程就提前重新持有了这把锁,导致临界区代码不能得到严格的串行执行。

不难发现正常情况下锁操作完后都会被手动释放,常见的解决方案是调大锁的超时时间,之后若再出现超时带来的并发问题,人工介入修正数据。这也不是一个完美的方案,因为但业务逻辑执行时间是不可控的࿰

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值