redis分布式锁常见问题及解决方案

redis分布式锁常见问题及解决方案,第1张

        11 锁需要具备唯一性

        12 锁需要有超时时间,防止死锁

        13 锁的创建和设置锁超时时间需要具备原子性

        14 锁的超时的续期问题

        15 B的锁被A给释放了的问题

        16 锁的可重入问题

        17 集群下分布式锁的问题

        问题讲解:

        首先分布式锁要解决的问题就是分布式环境下同一资源被多个进程进行访问和 *** 作的问题,既然是同一资源,那么肯定要考虑数据安全问题其实和单进程下加锁解锁的原理是一样的,单进程下需要考虑多线程对同一变量进行访问和修改问题,为了保证同一变量不被多个线程同时访问,按照顺序对变量进行修改,就要在访问变量时进行加锁,这个加锁可以是重量级锁,也可以是基于cas的乐观锁

        解决方案:

        使用redis命令setnx(set if not exist),即只能被一个客户端占坑,如果redis实例存在唯一键(key),如果再想在该键(key)上设置值,就会被拒绝

        问题讲解:

        redis释放锁需要客户端的 *** 作,如果此时客户端突然挂了,就没有释放锁的 *** 作了,也意味着其他客户端想要重新加锁,却加不了的问题

        解决方案:

        所以,为了避免客户端挂掉或者说是客户端不能正常释放锁的问题,需要在加锁的同时,给锁加上超时时间

        即,加锁和给锁加上超时时间的 *** 作如下 *** 作:

>setnx lockkey true    #加锁 *** 作

ok

>expire lockkey 5    #给锁加上超时时间

do something critical

>del lockkey    #释放锁

(integer) 1

        问题讲解:

        通过23加锁和超时时间的设置可以看到,setnx和expire需要两个命令来完成 *** 作,也就是需要两次RTT *** 作,如果在setnx和expire两次命令之间,客户端突然挂掉,这时又无法释放锁,且又回到了死锁的问题

        解决方案:

        使用set扩展命令

        如下:

>set lockkey true ex 5 nx   #加锁,过期时间5s

ok

do something critical

>del lockkey

        以上的set lockkey true ex 5 nx命令可以一次性完成setnx和expire两个 *** 作,也就是解决了原子性问题

        问题讲解:

        redis分布式锁过期,而业务逻辑没执行完的场景,不过,这里换一种思路想问题,把redis锁的过期时间再弄长点不就解决了吗?那还是有问题,我们可以在加锁的时候,手动调长redis锁的过期时间,可这个时间多长合适?业务逻辑的执行时间是不可控的,调的过长又会影响 *** 作性能。

        解决方案:

        使用redis客户端redisson,redisson很好的解决了redis在分布式环境下的一些棘手问题,它的宗旨就是让使用者减少对Redis的关注,将更多精力用在处理业务逻辑上。redisson对分布式锁做了很好封装,只需调用API即可。RLock lock = redissonClientgetLock("stockLock");

        redisson在加锁成功后,会注册一个定时任务监听这个锁,每隔10秒就去查看这个锁,如果还持有锁,就对过期时间进行续期。默认过期时间30秒。这个机制也被叫做:“看门狗”

        问题讲解:

        A、B两个线程来尝试给key myLock加锁,A线程先拿到锁(假如锁3秒后过期),B线程就在等待尝试获取锁,到这一点毛病没有。那如果此时业务逻辑比较耗时,执行时间已经超过redis锁过期时间,这时A线程的锁自动释放(删除key),B线程检测到myLock这个key不存在,执行 SETNX命令也拿到了锁。但是,此时A线程执行完业务逻辑之后,还是会去释放锁(删除key),这就导致B线程的锁被A线程给释放了。

      解决方案:

      一般我们在每个线程加锁时要带上自己独有的value值来标识,只释放指定value的key,否则就会出现释放锁混乱的场景一般我们可以设置value为业务前缀_当前线程ID或者uuid,只有当前value相同的才可以释放锁

        问题讲解:

        上面我们讲了,为了保证锁具有唯一性,需要使用setnx,后来为了与超时时间一起设置,我们选用了set命令。 在我们想要在加锁期间,拥有锁的客户端想要再次获得锁,也就是锁重入

        解决方案:

       给锁设置hash结构的加锁次数,每次加锁就+1

        问题讲解:

        这一问题是在redis集群方案时会出现的事实上,现在为了保证redis的高可用和访问性能,都会设置redis的主节点和从节点,主节点负责写 *** 作,从节点负责读 *** 作,也就意味着,我们所有的锁都要写在主redis服务器实例中,如果主redis服务器宕机,资源释放(在没有加持久化时候,如果加了持久化,这一问题会更加复杂),此时redis主节点的数据并没有复制到从服务器,此时,其他客户端就会趁机获取锁,而之前拥有锁的客户端可能还在对资源进行 *** 作,此时又会出现多客户端对同一资源进行访问和 *** 作的问题

        解决方案:

        使用redlock,原理与zookeeper分布式锁原理相同多台主机超过半数设置成功则获取锁成功,要注意下主机个数必须是奇数,不过这有效率问题

指纹注册 *** 作超时怎么办新建指纹录入时显示录入失败的原因有多种,如果您在录入手机指纹锁时录入失败,可以根据以下情况进行排查:1 录入指纹时,是否滑动手指如果手指有快速滑动,会导致指纹传感器获取的指纹图像质量不达标,导致录入失败,建议您录入时将手指放置在指纹感应区稍等片刻。2 手指和指纹传感器识别区域是否洁净如果手指或指纹传感器识别区域有汗液、水渍、脏污等,传感器也会智能识别,影响指纹的录入。3 录入时是否中途退出或屏幕长时间未 *** 作指纹录入过程中,如果中途退出录入界面或亮屏无 *** 作保持10分钟以上会导致录入失败,建议您重新录入,并及时将指纹录入完整。温馨提醒:中途退出录入界面或录入超时后需要重新输入密码进行录入,这样可以避免您的手机在未锁屏的状况下被其他人录入指纹,从而保护您的手机使用安全。4 请尽量使用手指不同位置录入,尽可能扩大指纹录入面积录入时请调整手指接触的位置和角度并适度按压,这样可以使指纹录入的面积增大,解锁时的成功的概率就越高;录入指纹的面积过小,录入位置单一,可能会导致录入失败或解锁成功率低。5 请尽量避免在充电时录入指纹。充电器可能会干扰指纹传感器,所以请尽量避免在充电时录入指纹

以上就是关于redis分布式锁常见问题及解决方案全部的内容,包括:redis分布式锁常见问题及解决方案、李文指纹锁录入超时怎样解除、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9384175.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存