基于Redisson实现分布式锁源码解读

一、分布式锁的概念 使用场景

二、将redis官网对于分布式锁(红锁)的定义和Redisson实现做概括性总结

三、基于Redisson的分布式实现方案

四、加锁过程分析

五、锁重入过程分析

六、未获取到锁的线程继续获取锁

七、锁释放过程分析

八、易混淆概念

 

一、分布式锁的概念 使用场景

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。

  在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,这个时候,便需要使用到分布式锁。

 

二、将redis官网对于分布式锁(红锁)的定义和Redisson实现做概括性总结

  该部分可以先粗略的浏览一下,领略其官方的理论定义,读完后续内容会对该环节有更清晰的理解。

  对于Redis分布式锁(红锁)官网定义:

基于Redisson实现分布式锁源码解读

       中文对如上5点做出解释:

redis红锁算法:

  在Redis的分布式环境中,我们假设有N个Redis master。这些节点完全互相独立,不存在主从复制或者其他集群协调机制。我们确保将在N个实例上使用与在Redis单实例下相同方法获取和释放锁。现在我们假设有5个Redis master节点,同时我们需要在5台服务器上面运行这些Redis实例,这样保证他们不会同时都宕掉。

  为了取到锁,客户端应该执行以下操作:

1、获取当前时间,以毫秒为单位。

2、依次尝试从5个实例,使用相同的key和随机值(Redisson中给出的是UUID + ThreadId)获取锁。当向Redis请求获取锁时,客户端应该设置一个网络连接和响应超时时间(我们接下来会在加锁的环节多次提到这个时间),这个超时时间应该小于锁的失效时间。例如你的锁自动失效时间为10秒,则超时时间应该在5-50毫秒之间。这样可以避免服务器端Redis已经挂掉的情况下,客户端还在一直等待响应结果。如果服务器端没有在规定时间内响应,客户端应该尽快尝试去另外一个Redis实例请求获取锁。

3、客户端使用当前时间减去开始获取锁时间(步骤1记录的时间)就得到获取锁使用的时间。当且仅当从大多数(N/2+1,这里是3个节点)的Redis节点都取到锁,并且使用的时间小于锁失效时间时,锁才算获取成功。

4、如果取到了锁,key的真正有效时间等于有效时间减去获取锁所使用的时间(步骤3计算的结果)。

5、如果因为某些原因,获取锁失败(没有在至少N/2+1个Redis实例取到锁或者取锁时间已经超过了有效时间),客户端应该在所有的Redis实例上进行解锁(即便某些Redis实例根本就没有加锁成功,防止某些节点获取到锁但是客户端没有得到响应而导致接下来的一段时间不能被重新获取锁)。

针对如上几点,redisson的实现:

基于Redisson实现分布式锁源码解读

 

 

基于Redisson实现分布式锁源码解读

 

 

 

三、基于Redisson的分布式实现方案

  在分析Redisson的源码前,先重申一下我们本文的重点放在分布式锁的加锁、锁重入、未获取到锁的线程继续获取锁、释放锁四个过程!希望可以对大家有所帮助。

  锁重入:我们假设,一次加锁时间为30秒,当然Redisson默认的也是30秒,但是业务执行时间大于30秒,如果没有锁重入的实现,那么30秒后锁失效,业务逻辑就会陷入无法保证正确性的严重后果中。

第一步:添加依赖 

<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.5</version> </dependency>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgfswx.html