国内最专业的IT技术学习网

UI设计

当前位置:主页 > 亚博体育app手机版 >

大家所推崇的Redis分布式锁真的就万无一失吗?

发布时间:2019/06/25标签:   分布式    点击量:

原标题:大家所推崇的Redis分布式锁真的就万无一失吗?
在单实例JVM中,罕见的处置并提问题的方式有许多,比方synchronized要害字停止拜访操纵、volatile要害字、ReentrantLock等罕用方式。然而在散布式情况中,上述方式却不能在跨JVM场景顶用于处置并提问题,当营业场景须要对散布式情况中的并提问题停止处置时,须要应用散布式锁来完成。散布式锁,是指在散布式的安排情况下,经过锁机制来让多客户端互斥的对同享资本停止拜访。现在比拟罕见的散布式锁完成计划有以下几种: 基于数据库,如MySQL 基于缓存,如Redis 基于Zookeeper、etcd等。这里先容一下怎样应用缓存(Redis)完成散布式锁。应用Redis完成散布式锁最简略的计划是应用下令SETNX。SETNX(SET if Not eXist)的应用方法为:SETNX key value,只在键key不存在的情形下,将键key的值设置为value,若键key存在,则SETNX不做任何举措。SETNX在设置胜利时前往,设置失利时前往0。当要猎取锁时,间接应用SETNX猎取锁,当要开释锁时,应用DEL下令删撤除对应的键key便可。下面这类计划有一个致命成绩,就是某个线程在猎取锁以后因为某些异样要素(比方宕机)而不能畸形的履行解锁操纵,那末这个锁就永久开释不掉了。为此,咱们能够为这个锁加上一个超不时间。第一时光咱们会遐想到Redis的EXPIRE下令(EXPIRE key seconds)。然而这里咱们不能应用EXPIRE来完成散布式锁,由于它与SETNX一同是两个操纵,在这两个操纵之间能够会产生异样,从而仍是达不到预期的成果,示比方下://STEP1SETNXkeyvalue//若在这里(STEP1和STEP2之间)顺序忽然瓦解,则无奈设置过时时光,将有能够无奈开释锁//STEP2EXPIREkeyexpireTime对此,准确的姿态应当是应用“SET key value [EX seconds] [PX milliseconds] [NX|XX]”这个下令。从 Redis 2.6.12 版本开端, SET 下令的行动能够经过一系列参数来修正: EX seconds : 将键的过时时光设置为 seconds 秒。 履行 SET key value EX seconds 的后果同等于履行 SETEX key seconds value 。 PX milliseconds : 将键的过时时光设置为 milliseconds 毫秒。 履行 SET key value PX milliseconds 的后果同等于履行 PSETEX key milliseconds value 。 NX : 只在键不存在时, 才对键停止设置操纵。 履行 SET key value NX 的后果同等于履行 SETNX key value 。 XX : 只在键曾经存在时, 才对键停止设置操纵。举例,咱们须要创立一个散布式锁,而且设置过时时光为10s,那末能够履行以下下令:SETlockKeylockValueEX10NX或许SETlockKeylockValuePX10000NX留神EX和PX不能同时应用,不然会报错:ERR syntax error。解锁的时间仍是应用DEL下令来解锁。修正以后的计划看下来很完善,但现实上仍是会有成绩。试想一下,某线程A猎取了锁而且设置了过时时光为10s,而后在履行营业逻辑的时间消耗了15s,此时线程A猎取的锁早已被Redis的过时机制主动开释了。在线程A猎取锁并经由10s以后,改锁能够曾经被别的线程猎取到了。当线程A履行完营业逻辑预备解锁(DEL key)的时间,有能够删撤除的是别的线程曾经猎取到的锁。以是最好的方法是在解锁时推断锁能否是本人的。咱们能够在设置key的时间将value设置为一个独一值uniqueValue(能够是随机值、UUID、或许呆板号+线程号的组合、署名等)。当解锁时,也就是删除key的时间先推断一下key对应的value能否即是先前设置的值,假如相称才干删除key,伪代码示比方下:ifuniqueKey==GET(key){DELkey}

版权信息Copyright ? IT技术教程 版权所有??? ICP备案编号:鲁ICP备09013610号