Redis分布式锁及Redisson的实现原理

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

Redis分布式锁

一。什么是分布式锁

在讨论分布式锁之前我们回顾一下一些单机锁,比如synchronized、Lock 等

锁的基本特性:

1.互斥性:同一时刻只能有一个节点访问共享资源,比如一个代码块,或者同一个订单同一时刻只能有一个线程去支付等。
2.可重入性: 允许一个已经获得锁的线程,在没有释放锁之前重新去获得锁
3.锁的获取和释放,锁的失效机制是避免死锁 的一个问题

分布式锁也是基于这些特性来实现的,只不过是在分布式环境中来实现的。

Redis分布式锁及Redisson的实现原理

那什么是分布式锁呢:

分布式锁独立于业务服务的,是一种跨进程的,跨机器节点的一种互斥锁。保证多个机器节点对共享资源访问的一个排他性。

二。自己设计一个锁,如何实现

先分析一下需求:

1.只能有一个线程能同时执行互斥的资源
2.其他的线程执行的时候,如果有线程要执行的话,要么等待,要么报错

实现方案:

1.要有一个标记来标记一个线程是不是在执行
比如说小黑屋,如何保证一个小黑屋只有一个人,就是门,如果一个人进去之后把门锁住,那就能保证一个小黑屋只能有一个人了
单机锁中的synchronized 是把这个标记放到对象头的,JUC中的Lock实现的时候也是有一个state来标记的
2.这个标记是可见的。
也就是说小黑屋里一个人进去之后 得让所有人能获取到这个小黑屋里有没有人的最新结果
如何解决呢 可以用 volatile
3.获取 这个标记不能同时抢占成功,这一步必须是安全的。
也就是说一个人进小黑屋,至少分三步,进门,关门,锁门
如果说这三个操作不是原子性的话,一个人虽然进去了,但是还没有锁门,另外一个人也是可以进的,这样就不能保证互斥性
比如说JUC的Lock是怎么实现的 是通过cas(Compare And Swap 比较交换)实现的

三。Redis是怎么实现分布式锁的

1.标记
Redis key-value 结构 这个key就作为一个标记,这个key存在就说明有人在做,如果不存在就说明没人在做
2.可见性
也就是说我再get的时候,其他线程是不能set的

Redis中是如何保证的呢?单线程来实现的 因为必须要set完之后才能get set和get是顺序执行的

3.保证原子性

setnx 是单线程执行的 setnx 是一个原子性的指令

Redis获取锁与占有锁不是原子的,导致锁失效

为什么要原子性可以看下图:

Redis分布式锁及Redisson的实现原理

4.保证原子性Redis还有两种方式

1.事务
multi 开启一个事务
exec 提交
discard 回滚
比如:

Redis分布式锁及Redisson的实现原理

提交之后才能看到数据

Redis分布式锁及Redisson的实现原理

回滚

Redis分布式锁及Redisson的实现原理

Redis分布式锁及Redisson的实现原理

事务中命令可以是原子的,但是不能根据中间的指令的结果来决定后续的逻辑,所以实现不了 if(exists(‘pay:111’) == 0) == true {set(‘pay:111’, 1)}

问题:两个开启的事务,同时修改一个值怎么办

用到了redis中的watch(监控)

如下:

Redis分布式锁及Redisson的实现原理

watch id  //开启监控
multi //开启一个事务
incr id //将id加1 但是没有提交事务

如果此时有另外一个客户端 再将 id加1 如下:

Redis分布式锁及Redisson的实现原理

此时回到第一个客户端 进行提交时 会报nil 也就是说不能执行

Redis分布式锁及Redisson的实现原理

2.Lua脚本

四。redis的发布订阅机制

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息,发布者可以向指定的渠道 (channel) 发送消息,订阅者如果订阅了该频道的话就能收到消息,从而实现多个客户端的通信效果。

Redis分布式锁及Redisson的实现原理

订阅的命令是SUBSCRIBE channel[channel …],可以订阅一个或多个频道,当有新消息通过PUBLISH命令发送给频道时,订阅者就能收到消息,就好像这样:

Redis分布式锁及Redisson的实现原理

开启两个客户端,一个订阅了频道channel1,另一个通过PUBLISH发送消息后,订阅的那个就能收到了,靠这种模式就能实现不同客户端之间的通信。

五。问题

我们知道了redis的这些特性,那如果redis想要实现分布式锁,就得考虑几个问题:
1.重入锁怎么做,同一个线程能加锁多次
重入锁为了防止死锁,因为自己等待自己很容易死锁
重入锁需要做到以下三点:
1.互斥key 大Key
2.知道线程信息 field
3.保存重入次数 value hincrby(线程安全的)
Redis中的Hash完美的解决

2.假如30s锁会过期,但是业务还没有执行完,锁失效了怎么办

redission中的看门狗机制

redission 实现分布式锁

分布式锁的核心功能其实就三个:加锁、解锁、设置锁超时。这三个功能也是我们研究Redisson分布式锁原理的方向。

首先看一下redission 实现分布式的原理图

Redis分布式锁及Redisson的实现原理

一。Redisson的源码

在使用Redisson加锁之前,需要先获取一个RLock实例对象,有了这个对象就可以调用lock、tryLock方法来完成加锁的功能

@Bean
    @Primary
    public Config redissonConfig() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + redisConfig.getHost() + ":" + redisConfig.getPort())
                .setPassword(redisConfig.getPassword())
                .setDatabase(redisConfig.getDatabase());
        return config;
    }
 
    @Bean
    @Primary
    public RedissonClient redissonClient(Config config) {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
 
String lockKey = String.format(RedisKeys.APPROVAL_ACTION_KEY, approveParamDto.getProcessInstanceId());
RLock lock = redissonClient.getLock(lockKey);

RLock是一个接口,具体的同步器需要实现该接口,当我们调用redisson.getLock()时,程序会初始化一个默认的同步执行器RedissonLock文章来源地址https://www.toymoban.com/news/detail-456186.html

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

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

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

相关文章

  • Redis实战——Redisson分布式锁

    目录 1 基于Redis中setnx方法的分布式锁的问题 2 Redisson         2.1 什么是Redisson         2.2 Redisson实现分布式锁快速入门         2.3 Redisson 可重入锁原理                 什么是可重入锁?                 Redisson中又是如何实现的呢?         2

    2024年02月15日
    浏览(49)
  • redis的分布式事务-redisson

    Redisson分布式锁是一种基于redis实现的分布式锁,它利用redis的setnx命令实现分布式锁的互斥访问。同时还支持锁的自动续期功能,可以避免因为某个进程崩溃或者网络故障导致锁无法释放的情况。 只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔

    2024年02月13日
    浏览(47)
  • redis缓存击穿,redisson分布式锁,redis逻辑过期

    什么是缓存击穿: 缓存击穿是指在高并发环境下,某个热点数据的缓存过期,导致大量请求同时访问后端存储系统,引起系统性能下降和后端存储压力过大的现象。 解决方案: 1. redisson分布式锁 本质上是缓存重建的过程中,大量的请求访问到后端的数据库导致数据库压力过

    2024年02月06日
    浏览(53)
  • Redisson分布式锁 原理&源码 分析

    获取锁的Lua脚本: 释放锁的Lua脚本: tryLock()底层代码分析 time :剩余的等待重试时间 ttl :现被持有的锁的剩余有效时间 计算尝试获取锁所消耗的时间,然后再计算出等待获取锁的剩余时间time, 如果time=0,则不再重试了直接返回获取锁失败, 如果time0,则通过subscribe去

    2024年02月11日
    浏览(65)
  • Redisson 分布式锁可重入的原理

    目录 1. 使用 Redis 实现分布式锁存在的问题 2. Redisson 的分布式锁解决不可重入问题的原理 不可重入:同一个线程无法两次 / 多次获取锁 举例 method1 执行需要获取锁 method2 执行也需要(同一把)锁 如果 method1 中调用了 method2,就会出现死锁的情况 method1 执行的过程是同一个线

    2024年01月25日
    浏览(44)
  • Redis分布式锁实现原理

    在早期互联网的架构中,一个应用都是单机进行部署,这种情况下,利用JDK提供的锁机制即可解决共享数据在多线程场景下的线程安全问题,但随着技术的发展,分布式系统架构逐渐普及,在分布式架构中,由于一个应用会进行多机部署,服务器实例之间的JVM是互相独立的,

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

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

    2024年01月20日
    浏览(51)
  • Redis实现分布式锁原理(面试重点)

    一、为什么使用分布式锁? 本地锁的局限性( synchronized ): 本地锁只能锁住当前服务,只能保证自己的服务,只有一个线程可以访问,但是在服务众多的分布式环境下,其实是有多个线程同时访问的同一个数据,这显然是不符合要求的。 ·分布式锁的概念: 分布式锁指的是,

    2024年02月10日
    浏览(42)
  • 深度解析Redisson框架的分布式锁运行原理与高级知识点

    分布式系统中的锁管理一直是一个复杂而关键的问 题。在这个领域,Redisson框架凭借其出色的性能和功能成为了开发者的首选之一。本篇博客将深入探讨Redisson框架的分布式锁运行原理以及涉及的高级知识点。通过详细的解释和示例代码,您将更好地理解如何在分布式环境中

    2024年02月09日
    浏览(46)
  • Redisson实现分布式锁示例

    可以下载redis desktop manager软件来查看redis里面存放的东西 红色框内的TTL值就是过期时间,默认-1,表示永不过期,指定过期时间后就变成你指定的值了。 上面的方法,我们让线程睡眠60S,代表我们的业务执行时间,在调用这个方法时,我们可以在 redis desktop manager软件上实时查

    2024年02月12日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包