Redis分布式锁常见问题
2022-10-24 17:34:43 17 举报
AI智能生成
Redis分布式锁常见问题
作者其他创作
大纲/内容
setNx命令
假如加锁成功,但是设置超时时间失败了,该lockKey就变成永不失效。假如在高并发场景中,有大量的lockKey加锁成功了,但不会失效,有可能直接导致redis内存空间不足。
非原子操作
set命令
lockKey:锁的标识requestId:请求idNX:只在键不存在时,才对键进行设置操作。PX:设置键的过期时间为 millisecond 毫秒。expireTime:过期时间set命令是原子操作,加锁和设置超时时间,一个命令就能轻松搞定。
超时时间才释放锁,不合理
手动加锁业务操作手动释放锁如果手动释放锁失败了,则达到超时时间,redis会自动释放锁。
合理的用法
忘了释放锁
假如线程A和线程B,都使用lockKey加锁。线程A加锁成功了,但是由于业务功能耗时时间很长,超过了设置的超时时间。这时候,redis会自动释放lockKey锁。此时,线程B就能给lockKey加锁成功了,接下来执行它的业务操作。恰好这个时候,线程A执行完了业务功能,接下来,在finally方法中释放了锁lockKey。这不就出问题了,线程B的锁,被线程A释放了
多设置了一个参数:requestId
释放了别人的锁
比如500毫秒内,自旋不断尝试加锁(说白了,就是在死循环中,不断尝试加锁),如果成功则直接返回。如果失败,则休眠50毫秒,再发起新一轮的尝试。如果到了超时时间,还未加锁成功,则直接返回失败。
大量失败请求
redis分布式锁是互斥的。假如我们对某个key加锁了,如果该key对应的锁还没失效,再用相同key去加锁,大概率会失败。
在递归方法中递归遍历多次,每次都是加的同一把锁。递归第一层当然是可以加锁成功的,但递归第二层、第三层...第N层,不就会加锁失败了?
因为从根节点开始,第一层递归加锁成功,还没释放锁,就直接进入第二层递归。因为锁名为lockKey,并且值为requestId的锁已经存在,所以第二层递归大概率会加锁失败,然后返回到第一层。第一层接下来正常释放锁,然后整个递归方法直接返回了。
特殊场景
redisson可重入锁
锁重入问题
写入的操作比较少,反而有大量读取的操作。这样直接使用普通的redis分布式锁,有点浪费性能
锁的粒度越粗,多个线程抢锁时竞争就越激烈,造成多个线程锁等待的时间也就越长,性能也就越差。
没有必要给读操作加互斥锁,只要保证读写、写写并发操作上锁是互斥的就行
读与读是共享的,不互斥读与写互斥写与写互斥
redisson.getReadWriteLock
读写锁
锁分段
锁竞争问题
TimerTask类,来实现自动续期
redisson
锁超时问题
如果redis存在多个实例。比如:做了主从,或者使用了哨兵模式,基于redis的分布式锁的功能
redis加锁操作,都在master上进行,加锁成功后,再异步同步给所有的slave。
master节点由于某些不可逆的原因,挂掉了这样需要找一个slave升级为新的master节点,假如slave1被选举出来了如果有个锁A比较悲催,刚加锁成功master就挂了,还没来得及同步到slave1这样会导致新master节点中的锁A丢失了。后面,如果有新的线程,使用锁A加锁,依然可以成功,分布式锁失效了。
redisson框架为了解决这个问题,提供了一个专门的类:RedissonRedLock,使用了Redlock算法。
主从复制的问题
Redis分布式锁
0 条评论
回复 删除
下一页