Redisson详解(分布式锁使用及实现原理)

Redisson详解(分布式锁使用及实现原理)-mikechen

Redisson定义

Redisson 是架设在 Redis 基础上的一个 Java 驻内存数据网格框架, 充分利用 Redis 键值数据库提供的一系列优势。

Redisson 基于 Java 实用工具包中常用接口, 为我们提供了一系列具有分布式特性的工具类。

 

Redisson使用

1.第一步:引入Redisson Maven 依赖

<dependency>

    <groupId>org.redisson</groupId>

    <artifactId>redisson</artifactId>

    <version>3.15.5</version>

</dependency>

 

2.自定义Redisson配置类

程序化的配置方法是通过构建Config对象实例来实现的,如下所示:

@Configuration
public class MyRedissonConfig {
    /**
     * 对 Redisson 的使用都是通过 RedissonClient 对象
     * @return
     * @throws IOException
     */
    @Bean(destroyMethod="shutdown") // 服务停止后调用 shutdown 方法。
    public RedissonClient redisson() throws IOException {
        // 1.创建配置
        Config config = new Config();
        // 集群模式
        // config.useClusterServers().addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");
        // 2.根据 Config 创建出 RedissonClient 示例。
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

3.测试Redisson配置类

我们运行这个测试方法,打印出 redissonClient

@Autowired
RedissonClient redissonClient;

@Test
public void TestRedisson() {
    System.out.println(redissonClient);
}

运行结果

org.redisson.Redisson@77f66138

说明Redisson配置成功了,之后通过@Autowired注入RedissonClient 就可以使用Redisson分布式锁等应用了。

 

Redisson分布式锁原理

Redisson这个框架对Redis分布式锁的实现原理图如下:

Redisson详解(分布式锁使用及实现原理)-mikechen

1:获取锁

一个Redission客户端1要加锁,它首先会根据hash节点选择一台机器,紧接着就会发送一段lua脚本到redis上,比如加锁的那个锁key就是”mylock”,并且设置的时间是30秒,30秒后mylock锁就会被释放。

 

2.锁互斥机制

如果这个时候Redission客户端2来加锁,它也会会根据hash节点选择一台机器,然后执行了同样的一段lua脚本。

它首先回来判断《mylock》这个锁存在吗?如果存在则Redission客户端2会获得一个数字,这个数字就是mylock这个锁的剩余生存时间。

此时Redission客户端2就会进入到一个while循环,就是CAS不停的自旋尝试加锁,知道成功为止。

 

3.看门狗机制

如果负责储存这个分布式锁的 Redisson 节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。

为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。

比如:

//设置锁1秒过去
redissonLock.lock("redisson", 1);
/**
 * 业务逻辑需要咨询2秒
 */
redissonLock.release("redisson");

线程A拿到锁需要处理2秒,但是锁的超时时间只有1秒,也就是说锁超时的时候,业务还没处理完。

这时候线程B就进来了又拿到锁,导致加锁跟解锁的时候并不是同一线程。

看门狗的作用就是当遇到这种情况的时候,看门狗会定时去查看一下这个线程A是否还在执行任务,如果还在执行则给他继续延长时间。

默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

// 设置看门狗时间,默认是30秒,我们设置为3秒
config.setLockWatchdogTimeout(3000L);
// 如果使用看门狗,一定要使用tryLock

 

4.可重入加锁机制

我们知道ReentrantLock是可重入锁,它的特点就是:同一个线程可以重复拿到同一个资源的锁,Redisson也能很好的满足这点。

Redisson 客户端1获得mylock锁时,里面会有一个hash结构的数据,如下图所示:

Redisson详解(分布式锁使用及实现原理)-mikechen

078e44a3-5f95-4e24-b6aa-80684655a15a:45它的组成是就是代表Redisson 客户端1,数字1就是代表这个客户端加锁了一次。

Redisson详解(分布式锁使用及实现原理)-mikechen

上面这图的意思就是可重入锁的机制,它最大的优点就是相同线程不需要在等待锁,而是可以直接进行相应操作。

 

5.释放锁机制

如果发现加锁次数变为0了,那么说明这个Redisson客户端1不再持有锁了,Redisson客户端2就可以加锁了。

 

评论交流
    说说你的看法