一种实现redis分布锁高可用的方法及其系统

文档序号:1952334 发布日期:2021-12-10 浏览:15次 >En<

阅读说明:本技术 一种实现redis分布锁高可用的方法及其系统 (Method and system for realizing high availability of redis distribution lock ) 是由 刘德建 叶伟 陈宏展 于 2021-09-14 设计创作,主要内容包括:本发明提供了一种实现redis分布锁高可用的方法,所述方法为:步骤S1、用户在客户端进行操作,触发分布式锁机制,设定一个时间戳beginTime;步骤S2、按顺序依次在所有redis服务节点上执行获取锁的操作,得到整个获取锁的过程总共消耗的时间;步骤S3、判断获取锁总共消耗的时间是否超过锁的有效时间,是,则提示获取锁失败;否,则进入步骤S4;步骤S4、判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,是,则获取锁成功,并在操作结束后释放锁,否,则提示获取锁失败;能有效防止锁丢失的问题。(The invention provides a method for realizing high availability of a redis distribution lock, which comprises the following steps: step S1, the user operates at the client to trigger the distributed locking mechanism and set a timestamp beginTime; step S2, executing lock acquisition operations on all redis service nodes in sequence to obtain the total time consumed in the whole lock acquisition process; step S3, judging whether the total consumed time for acquiring the lock exceeds the effective time of the lock, if so, prompting that the lock acquisition is failed; otherwise, go to step S4; step S4, judging whether more than half of the number of nodes in all redis service nodes successfully acquire the lock, if so, successfully acquiring the lock, releasing the lock after the operation is finished, and if not, prompting that the lock acquisition is failed; the problem of lock loss can be effectively prevented.)

一种实现redis分布锁高可用的方法及其系统

技术领域

本发明涉及计算机通讯技术领域,特别是一种实现redis分布锁高可用的方法及其系统。

背景技术

系统在商品库存的判断上,需要应用分布式锁来防止多台服务器并发导致库存超卖的情况。由于redis服务的命令执行部分是单线程顺序执行的,所以单节点的redis服务是可以保证原子性,利用redis来实现分布式锁被广泛应用,但是单节点难以保证高可用,如果redis服务节点宕机了,那么所有客户端就都无法获得锁了,系统服务将变得不可用。为了提高可用性,可以给这个redis节点挂一个从节点Slave服务器,当主节点Master服务器不可用的时候,系统自动切到从节点Slave服务器上。但由于redis的主从复制是异步的,这可能导致在数据同步的过程中丧失锁的安全性。

发明内容

为克服上述问题,本发明的目的是提供一种实现redis分布锁高可用的方法,避免了redis单点故障和redis集群异步同步数据发生宕机导致锁丢失的问题。

本发明采用以下方案实现:一种实现redis分布锁高可用的方法,所述方法包括如下步骤:

步骤S1、用户在客户端进行操作,触发分布式锁机制,设定一个时间戳beginTime;

步骤S2、按顺序依次在所有redis服务节点上执行获取锁的操作,得到整个获取锁的过程总共消耗的时间;

步骤S3、判断获取锁总共消耗的时间是否超过锁的有效时间,是,则提示获取锁失败;否,则进入步骤S4;

步骤S4、判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,是,则获取锁成功,并在操作结束后释放锁,否,则提示获取锁失败。

进一步的,所述步骤S1进一步具体为:用户在客户端进行操作,为了防止多台服务器并发导致库存超卖,此时触发分布式锁机制,读取当前时间,存储在时间戳beginTime上。

进一步的,所述步骤S2进一步具体为:为分布式锁机制设定一个缓存key,该缓存key=lock_商品编号;在本地配置文件提前配置好所有redis服务节点的IP和端口,通过读取配置文件得到redis服务节点列表,按顺序读取第一个redis服务节点的配置,获得第一个redis服务节点的IP和端口,连接redis服务节点,执行“setnx lock_商品编号”命令,如果redis服务节点返回0则取锁失败,如果redis服务节点返回1则获取锁成功,并使用一参数redis1LockStatus记录第一个redis服务节点获取锁的成功或者失败的结果;redis服务节点列表中剩余的redis服务节点按第一个redis服务节点的方式执行相同命令,把获取锁的结果记录在redis2LockStatus、redis3LockStatus、直至redisNLockStatus上;计算整个分布式锁的过程总共消耗的时间,即总共消耗的时间=所有redis服务节点获取锁时间的总和-时间戳beginTime。

进一步的,所述步骤S3进一步具体为:设置锁的有效时间expireTime,该有效时间expireTime为了防止服务异常状况,导致没有及时释放锁,判断获取锁总共消耗的时间totalTime是否超过锁的有效时间expireTime,是,则提示获取锁失败;否,则进入步骤S4。

进一步的,所述步骤S4进一步具体为:根据所有redis服务节点对应的参数redis1LockStatus、redis2LockStatus、redis3LockStatus、直至redisNLockStatus中的内容,判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,即参数redis1LockStatus记录“成功”,则表示获取到了锁,记录“失败”,则表示未获取到锁。

进一步的,所述步骤S4后进一步包括:步骤S5、重新计算锁剩余时间,即锁剩余时间=有效时间expireTime-总共消耗的时间totalTime,把计算得到的锁剩余时间重新赋值给参数expireTime;锁失效向所有redis服务节点发起锁释放操作,即如果用户完成商品购买库存扣减成功或者expireTime到期,则需要释放锁,依次连接所有redis服务节点,执行删除缓存key命令:del lock_商品编号,从而成功释放锁。

本发明还提供了一种实现redis分布锁高可用的系统,所述系统包括如下模块:触发模块、获取锁总耗时模块、判断时效模块、以及释放锁模块;

所述触发模块,在用户在客户端进行操作,触发分布式锁机制,设定一个时间戳beginTime;

所述获取锁总耗时模块,按顺序依次在所有redis服务节点上执行获取锁的操作,得到整个获取锁的过程总共消耗的时间;

所述判断时效模块,判断获取锁总共消耗的时间是否超过锁的有效时间,是,则提示获取锁失败;否,则执行释放锁模块;

所述释放锁模块,判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,是,则获取锁成功,并在操作结束后释放锁,否,则提示获取锁失败。

进一步的,所述触发模块的实现方式进一步具体为:用户在客户端进行操作,为了防止多台服务器并发导致库存超卖,此时触发分布式锁机制,读取当前时间,存储在时间戳beginTime上。

进一步的,所述获取锁总耗时模块的实现方式进一步具体为:为分布式锁机制设定一个缓存key,该缓存key=lock_商品编号;在本地配置文件提前配置好所有redis服务节点的IP和端口,通过读取配置文件得到redis服务节点列表,按顺序读取第一个redis服务节点的配置,获得第一个redis服务节点的IP和端口,连接redis服务节点,执行“setnxlock_商品编号”命令,如果redis服务节点返回0则取锁失败,如果redis服务节点返回1则获取锁成功,并使用一参数redis1LockStatus记录第一个redis服务节点获取锁的成功或者失败的结果;redis服务节点列表中剩余的redis服务节点按第一个redis服务节点的方式执行相同命令,把获取锁的结果记录在redis2LockStatus、redis3LockStatus、直至redisNLockStatus上;计算整个分布式锁的过程总共消耗的时间,即总共消耗的时间=所有redis服务节点获取锁时间的总和-时间戳beginTime。

进一步的,所述判断时效模块的实现方式进一步具体为:设置锁的有效时间expireTime,该有效时间expireTime为了防止服务异常状况,导致没有及时释放锁,判断获取锁总共消耗的时间totalTime是否超过锁的有效时间expireTime,是,则提示获取锁失败;否,则执行释放锁模块。

进一步的,所述释放锁模块的实现方式进一步具体为:根据所有redis服务节点对应的参数redis1LockStatus、redis2LockStatus、redis3LockStatus、直至redisNLockStatus中的内容,判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,即参数redis1LockStatus记录“成功”,则表示获取到了锁,记录“失败”,则表示未获取到锁。

进一步的,所述系统还包括重置时间模块,所述重置时间模块,用于重新计算锁剩余时间,即锁剩余时间=有效时间expireTime-总共消耗的时间totalTime,把计算得到的锁剩余时间重新赋值给参数expireTime;锁失效向所有redis服务节点发起锁释放操作,即如果用户完成商品购买库存扣减成功或者expireTime到期,则需要释放锁,依次连接所有redis服务节点,执行删除缓存key命令:del lock_商品编号,从而成功释放锁。

本发明的有益效果在于:避免了redis单点故障和redis集群异步同步数据发生宕机导致锁丢失的问题;应用多redis节点实现分布式锁的高可用,如果大于一半的redis节点成功获取到了锁,并且获取锁总共消耗的时间没有超过锁的有效时间,那么才认为最终获取锁成功,防止库存超卖的情况;redis服务在分布式锁实现上的高可用方案,采用多节点共同加锁来实现多份锁数据,如果某个redis宕机也不会导致锁丢失。

附图说明

图1是本发明的方法流程示意图。

图2是本发明的系统原理框图。

具体实施方式

下面结合附图对本发明做进一步说明。

本发明提供了一种实现redis分布锁高可用的方法,基于redis的命令执行部分是单线程顺序执行的这一特性,所以单节点的redis的分布式锁的实现方案是利用setnx命令,setnx是SET if Not eXists的缩写,存储一个值到缓存key中,如果此缓存key存在则返回0,不存在则执行保存set命令成功则后返回1,再配合缓存key的过期时间实现锁超时过期机制。在单节点实现分布式锁的基础之前,为了分布式锁高可用,需要部署多个redis节点配合使用。在读锁时,设定一个时间戳beginTime,按顺序依次在所有redis节点上执行获取锁的操作,计算出整个获取锁的过程总共消耗了多长时间。如果大于一半的redis节点成功获取到了锁,并且获取锁总共消耗的时间没有超过锁的有效时间,那么才认为最终获取锁成功;否则认为最终获取锁失败。

请参阅图1所示,本发明的所述方法包括如下步骤:

步骤S1、用户在客户端进行操作,触发分布式锁机制,设定一个时间戳beginTime;

步骤S2、按顺序依次在所有redis服务节点上执行获取锁的操作,得到整个获取锁的过程总共消耗的时间;

步骤S3、判断获取锁总共消耗的时间是否超过锁的有效时间,是,则提示获取锁失败;否,则进入步骤S4;

步骤S4、判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,是,则获取锁成功,并在操作结束后释放锁,否,则提示获取锁失败。

下面结合一具体实施例对本发明做进一步说明:

一种实现redis分布锁高可用的方法,步骤1、用户购买商品,触发锁机制:

用户进入客户端的商品详情,点击购买商品,系统需要判断此时库存是否充足,为了防止多台服务器并发导致库存超卖,此时触发分布式锁机制。

步骤2、获取当前时间beginTime:

读取当前时间,存储在beginTime上,假设此时beginTime=2021-08-08 19:14:50,当前时间是为了后续计算整个获取锁的总耗时用的。

步骤3、组织缓存key,缓存key=lock_商品编号:

为此次的锁业务设定一个缓存key=lock_商品编号,假设此次购买商品的编号goodsId=54321,那么缓存key=lock_54321。

步骤4、读取redis节点列表,含3个节点:

在本地配置文件提前配置好3个redis节点的IP和端口,通过读取配置文件得到redis节点列表。

步骤5、连接第一个redis节点,执行setnx命令:

读取第一个redis节点的配置,获得redis1的IP和端口,连接redis,执行setnxlock_54321,如果redis返回0则取锁失败,如果redis返回1则获取锁成功。并记录第一个redis节点获取锁的结果,该结果为成功还是失败,记录在redis1LockStatus上。

步骤6、设置缓存key的锁过期时间2-10秒,较佳的为3秒:

如果redis节点1获取锁成功,则设置key的过期时间expireTime为3秒,设置过期时间是为了防止服务异常状况,导致没有及时释放锁,导致redis节点1死锁。

步骤7、按顺序依次连接剩余redis节点列表上的节点,执行5、6步骤获取锁。

执行完redis节点1的获取锁后,重复步骤5、6,在剩下的redis节点2和redis节点3上也执行相同命令,把获取锁结果记录在redis2LockStatus和redis3LockStatus上。

步骤8、判断总耗时是否超过锁时间:

计算整个分布式锁的获取时间,也就是redis3个节点的获取锁时间的总和,计算方式是当前时间减去步骤2获取的beginTime,总消耗时间totalTime,如果超过步骤6设定的锁过期时间3秒则获取锁失效,如果小于锁超时时间则进入步骤9。

步骤9、判断获取锁成功节点数是否大于一半:

判断步骤5到步骤8得到redis1LockStatus、redis2LockStatus、redis3LockStatus,3台redis节点获取锁的结果中如果有2个以上(包括2个)则获取分布式锁成功,如果没有则获取锁失败。

步骤10、重新计算锁剩余时间,锁的有效时间减去步骤8的总耗时:

成功获取分布式锁后,需要重新计算锁的剩余时间,原先设定锁的过期时间为3秒,那么计算后锁的剩余时间为expireTime3秒减去步骤8的totalTime,把计算得到的时间重新赋值给expireTime。

步骤11、锁失效向所有redis节点发起锁释放操作,删除lock_goodsId:

如果用户完成商品购买库存扣减成功或者expireTime到期,则需要释放锁,依次连接3台redis,执行删除key命令:del lock_goodsId。删除成功则成功释放锁。

请参阅图2所示,本发明还提供了一种实现redis分布锁高可用的系统,所述系统包括如下模块:触发模块、获取锁总耗时模块、判断时效模块、以及释放锁模块;

所述触发模块,在用户在客户端进行操作,触发分布式锁机制,设定一个时间戳beginTime;所述触发模块的实现方式进一步具体为:用户在客户端进行操作,为了防止多台服务器并发导致库存超卖,此时触发分布式锁机制,读取当前时间,存储在时间戳beginTime上。

所述获取锁总耗时模块,按顺序依次在所有redis服务节点上执行获取锁的操作,得到整个获取锁的过程总共消耗的时间;

所述判断时效模块,判断获取锁总共消耗的时间是否超过锁的有效时间,是,则提示获取锁失败;否,则执行释放锁模块;

所述释放锁模块,判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,是,则获取锁成功,并在操作结束后释放锁,否,则提示获取锁失败。

所述获取锁总耗时模块的实现方式进一步具体为:为分布式锁机制设定一个缓存key,该缓存key=lock_商品编号;在本地配置文件提前配置好所有redis服务节点的IP和端口,通过读取配置文件得到redis服务节点列表,按顺序读取第一个redis服务节点的配置,获得第一个redis服务节点的IP和端口,连接redis服务节点,执行“setnx lock_商品编号”命令,如果redis服务节点返回0则取锁失败,如果redis服务节点返回1则获取锁成功,并使用一参数redis1LockStatus记录第一个redis服务节点获取锁的成功或者失败的结果;redis服务节点列表中剩余的redis服务节点按第一个redis服务节点的方式执行相同命令,把获取锁的结果记录在redis2LockStatus、redis3LockStatus、直至redisNLockStatus上;计算整个分布式锁的过程总共消耗的时间,即总共消耗的时间=所有redis服务节点获取锁时间的总和-时间戳beginTime。

所述判断时效模块的实现方式进一步具体为:设置锁的有效时间expireTime,该有效时间expireTime为了防止服务异常状况,导致没有及时释放锁,判断获取锁总共消耗的时间totalTime是否超过锁的有效时间expireTime,是,则提示获取锁失败;否,则执行释放锁模块。

所述释放锁模块的实现方式进一步具体为:根据所有redis服务节点对应的参数redis1LockStatus、redis2LockStatus、redis3LockStatus、直至redisNLockStatus中的内容,判断所有redis服务节点中是否超过一半的节点数量成功获取到了锁,即参数redis1LockStatus记录“成功”,则表示获取到了锁,记录“失败”,则表示未获取到锁。

所述系统还包括重置时间模块,所述重置时间模块,用于重新计算锁剩余时间,即锁剩余时间=有效时间expireTime-总共消耗的时间totalTime,把计算得到的锁剩余时间重新赋值给参数expireTime;锁失效向所有redis服务节点发起锁释放操作,即如果用户完成商品购买库存扣减成功或者expireTime到期,则需要释放锁,依次连接所有redis服务节点,执行删除缓存key命令:del lock_商品编号,从而成功释放锁。

以上所述仅为本发明的较佳实施例,凡依本发明申请专利范围所做的均等变化与修饰,皆应属本发明的涵盖范围。

9页详细技术资料下载
上一篇:一种医用注射器针头装配设备
下一篇:分布式事务处理方法、装置、计算机系统和可读存储介质

网友询问留言

已有0条留言

还没有人留言评论。精彩留言会获得点赞!

精彩留言,会给你点赞!