Redis实战——Redisson分布式锁

这篇具有很好参考价值的文章主要介绍了Redis实战——Redisson分布式锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1 基于Redis中setnx方法的分布式锁的问题

2 Redisson

        2.1 什么是Redisson

        2.2 Redisson实现分布式锁快速入门

        2.3 Redisson 可重入锁原理

                什么是可重入锁?

                Redisson中又是如何实现的呢?

        2.4 Redisson分布式锁的可重试性

        2.5 Redisson分布式锁的主从一致性(MutiLock锁)


1 基于Redis中setnx方法的分布式锁的问题

之前我们使用setnx方法自定义的分布式锁,仍然会有许多的问题:

主要分为下面5点

1. 不可重入:即同一个线程无法多次获取同一把锁。

2. 不可重试获取锁只尝试一次就返回false,没有重试机制

3. 超时释放:锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致锁释放,存在安全隐患

4. 主从一致性如果Redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从并同步主中的锁数据,则会出现锁实现。

redisson分布式锁使用,Redis,redis,数据库,java

这就需要我们去使用Redisson

2 Redisson

2.1 什么是Redisson

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

说人话,它是一个基于Redis实现的分布式工具的集合,其中就包含了各种分布式锁的实现。

官网地址: https://redisson.org

GitHub地址: GitHub - redisson/redisson: Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Publish / Subscribe, Bloom filter, Spring Cache, Tomcat, Scheduler, JCache API, Hibernate, MyBatis, RPC, local cache ...

redisson分布式锁使用,Redis,redis,数据库,java

 2.2 Redisson实现分布式锁快速入门

第一步,先引依赖。

 <!--Redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.13.6</version>
        </dependency>

第二步,配置Redisson客户端

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient(){
        // 配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.150.101:6379")
            .setPassword("123321");
        // 创建RedissonClient对象
        return Redisson.create(config);
    }
}

然后就可以使用Redisson中的getLock方法获取锁对象了。

在锁对象中通过tryLock方法尝试获取锁,该方法可以传入三个参数,分别是,获取锁失败的等待时间、超时时间和时间单位。默认分别是 -1秒(也就是不等待),30秒 和秒单位。

 //1.创建锁对象
        //SimpleRedisLock lock = new SimpleRedisLock(stringRedisTemplate, "order:" + userId);
        RLock lock = redissonClient.getLock("order:" + userId);

        //2.尝试获取锁
        boolean isLock = lock.tryLock();
        if (!isLock){
            //获取锁失败
            return Result.fail("一个用户只能下一单!");
        }
        try {
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.createVoucherOrder(voucherId);
        } finally {
            //释放锁
            lock.unlock();
        }

 2.3 Redisson 可重入锁原理

什么是可重入锁?

先看一段代码:

redisson分布式锁使用,Redis,redis,数据库,java

 方法1,先尝试获取锁,当获取锁成功后,调用方法2,在方法2中,又尝试获取锁,并执行完方法2的逻辑后,执行方法1 的逻辑,最后释放锁。

这个时候,因为方法1和方法2在同一个线程里,所以获取的是同一把锁,所以方法2中获取到的锁就是可重入锁。

Redisson中又是如何实现的呢?

很简单,就是新增了一个获取锁的次数。它舍弃了我们之前使用的Redis中String类型的setnx方法,改成用Hash类型的方法,分别存入锁的key,value存线程标识和锁的次数。

redisson分布式锁使用,Redis,redis,数据库,java

当同一个中的方法获取到同一把锁后,锁的次数+1,在释放锁的时候,不仅判断线程标识是否是自己的,还要判断锁的次数,如果次数-1 为0,采取释放锁。 以此来实现可重入锁。

 redisson分布式锁使用,Redis,redis,数据库,java

我们可以根据此图来实现Lua脚本:

获取锁

redisson分布式锁使用,Redis,redis,数据库,java

释放锁:

redisson分布式锁使用,Redis,redis,数据库,java

2.4 Redisson分布式锁的可重试性

直接看底层实现原理:

这里主要三点:

1.当锁超时时间过期时,会使用看门口WatchDog不断重新设置超时时间去重试获取锁

2. 看门狗只有在我们没有设置超时时间,在超时时间默认的情况下才会有。

3.在每次重新获取锁之前,不会马上不断的进行去重试,会等待是否有释放锁的信号和不断的精确判断剩余超时时间是否充裕。

redisson分布式锁使用,Redis,redis,数据库,java

 这样就能实现锁的重试了。

 2.5 Redisson分布式锁的主从一致性(MutiLock锁)

主从一致性问题:

为了提高redis的可用性,我们会搭建集群或者主从,现在以主从为例

此时我们去写命令,写在主机上, 主机会将数据同步给从机,但是假设在主机还没有来得及把数据写入到从机去的时候,此时主机宕机,哨兵会发现主机宕机,并且选举一个slave变成master,而此时新的master中实际上并没有锁信息,此时锁信息就已经丢掉了。、

redisson分布式锁使用,Redis,redis,数据库,java

为了解决这个问题,redission提出来了MutiLock锁,使用这把锁咱们就不使用主从了,每个节点的地位都是一样的, 这把锁加锁的逻辑需要写入到每一个主丛节点上,只有所有的服务器都写入成功,此时才是加锁成功,假设现在某个节点挂了,那么他去获得锁的时候,只要有一个节点拿不到,都不能算是加锁成功,就保证了加锁的可靠性。 

redisson分布式锁使用,Redis,redis,数据库,java

那么MutiLock 加锁原理是什么呢?笔者画了一幅图来说明

当我们去设置了多个锁时,redission会将多个锁添加到一个集合中,然后用while循环去不停去尝试拿锁,但是会有一个总共的加锁时间,这个时间是用需要加锁的个数 * 1500ms ,假设有3个锁,那么时间就是4500ms,假设在这4500ms内,所有的锁都加锁成功, 那么此时才算是加锁成功,如果在4500ms有线程加锁失败,则会再次去进行重试.

redisson分布式锁使用,Redis,redis,数据库,java文章来源地址https://www.toymoban.com/news/detail-605914.html

到了这里,关于Redis实战——Redisson分布式锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【实践篇】Redis最强Java客户端(三)之Redisson 7种分布式锁使用指南

    【实践篇】Redis最强Java客户端(三)之Redisson 7种分布式锁使用指南

    前两章我们了解了《【实践篇】Redis最强Java客户端(一)之Redisson入门介绍》和《【实践篇】Redis最强Java客户端(二)之Redisson基础概念》本章第三章主要介绍Redisson的七种分布式锁,分别是简单锁、公平锁、可重入锁、红锁、读写锁、信号量和闭锁。下面是每种锁的基本概念、使用

    2024年02月09日
    浏览(17)
  • 【业务功能100】补充代码【业务功能88】微服务-springcloud-分布式锁-redis-redisson-springcache

    采用redisson做分布式锁,完成数据的查询接口功能getCatelog2JSONRedis 原先从mysql数据库查询的效率较低,现在将部分固定数据展示比如页面的树形栏目信息等,存储到 redis缓存 ,然后基于分布式集群,需要结合本地锁(synchronized )与分布式锁(redissonClient.getLock(“catelog2JSON-lock”

    2024年02月09日
    浏览(19)
  • 在Java项目中使用redisson实现分布式锁

    在Java项目中使用Redission自定义注解实现分布式锁: 添加Redission依赖项:在项目的pom.xml中添加Redission依赖项: 创建自定义注解:创建一个自定义注解来标记需要使用分布式锁的方法。例如,创建一个名为 @DistributedLock 的注解: 创建注解切面:创建一个切面类,通过AOP将注解

    2024年02月16日
    浏览(13)
  • Redisson 分布式限流器 RRateLimiter 的使用及原理

    trySetRate 用于设置限流参数。其中 RateType 包含 OVERALL 和 PER_CLIENT 两个枚举常量,分别表示全局限流和单机限流。后面三个参数表明了令牌的生成速率,即每 rateInterval 生成 rate 个令牌, rateIntervalUnit 为 rateInterval 的时间单位。 acquire 和 tryAcquire 均可用于获取指定数量的令牌,不

    2024年01月20日
    浏览(10)
  • 【Redisson】Redisson--分布式中几种锁

    Redisson系列文章: 【Redisson】Redisson–基础入门 【Redisson】Redisson–布隆(Bloom Filter)过滤器 【Redisson】Redisson–分布式锁的使用(推荐使用) 【分布式锁】Redisson分布式锁底层原理 【Redisson】Redisson–限流器、 【Redisson】Redisson–分布式远程服务(Remote Service) 【Redisson】Redisson–

    2024年02月13日
    浏览(14)
  • 【Redisson】Redisson--分布式远程服务(Remote Service)

    【Redisson】Redisson--分布式远程服务(Remote Service)

    Redisson系列文章: 【Redisson】Redisson–基础入门 【Redisson】Redisson–布隆(Bloom Filter)过滤器 【Redisson】Redisson–分布式锁的使用(推荐使用) 【分布式锁】Redisson分布式锁底层原理 【Redisson】Redisson–限流器 当前有两台服务器连接的是同一个Redisson中间件,这两台服务器叫它们

    2024年02月13日
    浏览(12)
  • Redisson 分布式锁

    Redisson 分布式锁

    Redis是基础客户端库,可用于执行基本操作。 Redisson是基于Redis的Java客户端,提供高级功能如分布式锁、分布式集合和分布式对象。 Redisson提供更友好的API,支持异步和响应式编程,提供内置线程安全和失败重试机制。 实现步骤: 通过导入坐标和配置,注入RedissonClient对象之

    2024年02月11日
    浏览(16)
  • Redisson—分布式对象

    每个Redisson对象实例都会有一个与之对应的Redis数据实例,可以通过调用getName方法来取得Redis数据实例的名称(key)。 所有与Redis key相关的操作都归纳在RKeys这个接口里: Redisson的分布式RBucketJava对象是一种通用对象桶可以用来存放任类型的对象。 除了同步接口外,还提供了异

    2024年02月07日
    浏览(10)
  • Redisson分布式锁

    Redisson分布式锁

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格,可参考Redisson官方文档使用,它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。 简单来说,就是直接 RLock rlock = redissonClient.getLock(“lock”); 获取到锁,然后lock()和unlock()即可。 并发达到了660,比之

    2024年02月16日
    浏览(14)
  • 运用分布式锁 redisson

    导入依赖 根据springboot版本不同自行选择版本 dependency groupIdorg.redisson/groupId artifactIdredisson-spring-boot-starter/artifactId version3.15.3/version /dependency 创建客户端

    2024年01月19日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包