您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

Redisson看门狗机制你了解多少

时间:2023-08-22 13:59:23  来源:  作者:java小悠

前言

谈到redisson就不得不说Redis了,一想到Redis就不得不想到并发编程锁机制,一想到锁机制那么就不能不考虑一个很头疼的问题,如何保证原子性的问题,高QPS请求量的系统对每次执行数据的原子性由为的关键,保证不了原子性就会导致一系列重复提交的操作,重复的数据导致在某些逻辑运算的时候发生误差;

ACID的特性首先是原子性,原子性永远是放在首位的,所以我们首先要解决的就是接口请求的原子性;

Redis分布式锁的原子性

Redis分布式锁到底能不能保证原子性,这是面试会被经常问到的一个问题。大部分的人回答都是不能保证原子性,但是其中的所以然大家都很模糊,我也一样,但为什么还在用Redis的分布式锁,如何让它可以具有原子性呢?

Redis分布式锁实现

SET NX相信大家都知道是redis实现加锁的一个命令,这里用Jedis封装的Api接口去对redis进行使用,Jedis是Redis官方推荐的面向JAVA操作Redis的客户段,RedisTemplate是SpringDataRedis中对Redis的封装客户端,方便的就是可以搭配Spring框架使用,如Spring cache

先上代码吧,这是我曾经写的一段关于redis分布式锁的代码,主要用于重复提交的判断,这里我用了jedis的setnx方法,加锁后的返回不为null && 值等于1的时候表示加锁成功,并且调用expire方法对key进行赋过期时间,业务处理完成后进行锁的释放,防止死锁,这里是常规的redis的加锁方式;

java复制代码
/**
 * 分布式事务锁-判断是否请求过
 * 
 * @param key 键
 * @param time 过期时间
 * @return true:存在
 */
@HystrixCommand(fallbackMethod = "isExistFAIl")
public boolean isExist(String key, int time) {
    Jedis jedis = null;
    try {
        jedis = jedisPoolManager.getJedis();
        String uniqKey = JEDIS_KEYNAME + key;
        String val = jedis.get(uniqKey);
        if (val != null) {
            return true;
        }

        if (lock.tryLock(1, TimeUnit.SECONDS)) {
            try {
                    Long flag = jedis.setnx(uniqKey, LOCAL_VAL);
                if (flag != null && flag.intValue() == 1) {
                    jedis.expire(uniqKey, time);
                } else {
                    throw new ExceptionTyche("加锁失败! ");
                }
            } finally {
                lock.unlock();
            }
        } else {
            log.info("执行Redis超时!直接返回!");
        }
    } catch (Exception e) {
        log.warn("Redis缓存异常! key={} errMsg:" + e.getMessage(), key, e);
    } finally {
        jedisPoolManager.close(jedis); // !!!关闭
    }
    return false;
}

细心的小伙伴可以看到, 我在setnx加锁之前,用了lock.tryLock这个方法,用jdk的锁先尝试进行获取锁,如果没有获取到直接返回,这样就能在一定程度上避免通过redis加锁后,业务逻辑还未执行完锁超时进行释放,导致下次同样的key获取到锁就会出现重复提交的操作

并且使用了HystrixCommand熔断注解,防止在高并发的情况下加锁方法出现异常,对其进行降级,保证业务提交的原子性;

Redisson分布式锁的原子性

关于Redisson是目前使用比较多的一个关于分布式锁的客户端,其主要原理相信大家知道,那就是watchDog机制,俗称“看门狗机制”,由于这种机制能对锁的过期时间进行续期在很大程度上能保证加锁的原子性;

关于Redisson的分布式锁之前的文章写过,通过注解的方式去实现juejin.cn/post/721514…

Redisson看门狗机制

前段时间突然遇到了这么一个问题,Redisson锁是统一进行续期的还是分开续期的,之前确实没有考虑过,下面来看下源码具体分析下;

这里我使用的是,redisson3.8.2的版本

xml复制代码<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.8.2</version>
</dependency>

这个方法是Redisson加锁的核心代码,本质也是通过redis的lua脚本;

加锁原理

 

代码解读:*KEYS[1]*加锁key,*ARGV[2]*加锁的值,*ARGV[1]*看门狗机制的过期时间,internalLockLeaseTime续期时间;

  • 第一个if:如果key不存在,则通过hest去加锁,KEYS[1]加锁key,ARGV[2]加锁的值,pexpire命令设置对key值设置过期时间;
  • 第二个if:key存在的情况,hincrby命令判断是不是自己的线程,如果是自己的线程的情况下,就对已经加锁的线程+1操作,并且设置过期时间,这也是可重入锁的一种实现;
  • 直接return,加锁失败,如果key值不是自己所在的线程则返回过期时间;

解锁原理

 

既然有加锁,相对肯定有解锁实现;

  • 第一个if:判断加锁key存不存在,*KEYS[2]*这里代表发布订阅消息的管道名称;
  • 第二个if:判断KEY[1]的ARGV[3]是否存在,*APGV[3]*代表线程id标识,如果不存在则返回null;
  • 第三方if:如果存在将APGV[3]的值减一,如果counter的值相当于线程id标识经过运算后的值大于0,由于是可重入锁,该线程依旧可以获取到锁,重新设置*ARGV[2]*锁过期时间,返回0;
  • del操作是真正的解锁操作,并且通过publish命令发布消息,*APGV[1]*代表消息内容,操作成功后返回1;
  • 解锁失败返回nil,nil相当于Java中的null;

Watchdog锁续期

通过对redisson的加锁、解锁源码分析,相信大家对这块已经有个很清楚的认识, 还有就是只有当前线程才是获取自己的锁,不是当前线程无法获取到锁,就意味着无法进行锁续期的操作 ,由此可证明Redisson锁的续期是分开进行的
commandExecutor.evalWriteAsync的加锁方法比较长,这里就不截出来了,有兴趣的小伙伴可以去追踪看看;

主要续期逻辑就是,例如一个线程加锁成功,就是自动触发Watchdog锁续期机制,后台是一个工作线程,每隔10秒钟的时间会check当前线程是否还持有锁,如果持有锁就将锁的过期时间延长至30秒;

总结

这里也是对之前redisson锁的知识遗漏点的一个学习,结合实际的业务开发使用的案例,来分析锁的底层原理,从而来避免我在使用过程中遇到问题,能有更加清晰的解决思路,理解不对的地方也欢迎大家在评论区提出。


原文链接:
https://juejin.cn/post/7269385060612309007



Tags:Redisson   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Redisson杂谈,你学到了什么?
一.Redisson 简介Redisson 是一个基于 Netty 通信框架的高性能 Redis 客户端, 实现了分布式和可扩展的 Java 数据结构,提供很多分布式相关操作服务以及大量便利的工具方法,让...【详细内容】
2023-10-16  Search: Redisson  点击:(297)  评论:(0)  加入收藏
Redisson锁机制源码分析
1、了解分布式锁的特性 1、锁的互斥性 也就是说,在任意时刻,只能有一个客户端能获取到锁,不能同时有两个或多个客户端获取到锁。 简单来说,就比如上厕所,一个厕所只有一个坑位...【详细内容】
2023-08-28  Search: Redisson  点击:(259)  评论:(0)  加入收藏
Springboot+Redisson封装分布式锁Starter
我们将分布式锁基于缓存扩展了一版,也就是说本starter即有分布式缓存功能,又有分布式锁功能。而注解版的分布式锁能够解决大多数场景的并核问题,小粒度的Lock锁方式补全其他场...【详细内容】
2023-08-28  Search: Redisson  点击:(254)  评论:(0)  加入收藏
Redisson看门狗机制你了解多少
前言谈到Redisson就不得不说Redis了,一想到Redis就不得不想到并发编程锁机制,一想到锁机制那么就不能不考虑一个很头疼的问题,如何保证原子性的问题,高QPS请求量的系统对每次执...【详细内容】
2023-08-22  Search: Redisson  点击:(195)  评论:(0)  加入收藏
Jedis 与 Redisson 对比有什么优缺点?
Jedis 和 Redisson 都是 Java 开发者广泛使用的 Redis Java 客户端之一。它们能够很好地与 Redis 数据库进行交互,提供丰富的功能和灵活的配置选项。虽然它们都可以用于在 Ja...【详细内容】
2023-05-18  Search: Redisson  点击:(438)  评论:(0)  加入收藏
一文看懂Redisson分布式锁的Watchdog机制源码实现
一、 分布式锁简介分布式锁是一种常见的协调分布式系统的机制,在分布式环境下保证数据的一致性和可用性。分布式锁的实现有很多种方式,其中较为常见的方式是利用Redis实现分布...【详细内容】
2023-04-12  Search: Redisson  点击:(247)  评论:(0)  加入收藏
使用redisson实现分布式秒杀功能
redisson相比原生的jredis具有排队的功能,不一致秒杀时,一时获取锁失败就返回失败。秒杀的原理就是使用redis的分布式锁的功能,保证每次抢购不会出现超卖的情况 1 引入pom...【详细内容】
2022-09-01  Search: Redisson  点击:(466)  评论:(0)  加入收藏
厉害了,原来 Redisson 这么好用
Redis 是最流行的 NoSQL 数据库是解决方案之一,而 Java 是世界上最流行(注意,我没有说“最好”)的编程语言之一。虽然两者看起来很自然地在一起“工作”,但是要知道,Redis 其实并...【详细内容】
2022-06-17  Search: Redisson  点击:(740)  评论:(0)  加入收藏
聊一聊Redis官方置顶推荐的Java客户端Redisson
写这篇的时候,相信有很多朋友还在用Jedis作为Redis的客户端,我不禁有很多问号,Jedis还香吗?如果你早些年说它香我信,但是都2020年了,它真的不那么香了。那为什么还继续使用它呢?大...【详细内容】
2020-10-12  Search: Redisson  点击:(412)  评论:(0)  加入收藏
Redis的三个框架:Jedis,Redisson,Lettuce
Jedis api 在线网址:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.htmlredisson 官网地址:https://redisson.org/redisson git项目地址:https://githu...【详细内容】
2019-11-11  Search: Redisson  点击:(1118)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
站内最新
站内热门
站内头条