当前位置: 首页 > news >正文

Redis系列---Redission分布式锁

文章目录

  • 类型
  • 原理
  • 使用
  • 看门狗
  • 与setNx比较

类型

使用Redission,lock的机制其实是使用了ttl,一直等ttl为0再get。无论是redission还是redis的setNx,只要是锁,都必须有加锁和释放锁两个动作,二者缺一不可,并且需要把释放锁放到final中,这样可以保证锁一定被释放。 lock和unlock必须搭配使用,缺一不可。
redission中常用的lock就两个,一个是lock一个是trylock。两者都是阻塞加锁, 前者会一直阻塞,相应的该方法不存在返回值,因为无意义;后者可以传入一个等待时间,等待时间内持续阻塞,相应的该方法存在返回值,因为要确认是否成功加了锁。根据业务场景自己判断使用哪种锁,二者其实相似,trylock就是lock的进阶,加了一个等待时间而已。

trylock:public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)public boolean tryLock(long waitTime, TimeUnit unit)public boolean tryLock() lock:public void lock()public void lock(long leaseTime, TimeUnit unit) private void lock(long leaseTime, TimeUnit unit, boolean interruptibly)waitTime等待/阻塞时间,tryLock若没有则等同于lock;
leaseTime锁持续时间;
unit时间单位。
其实大部分的重载方法都是将参数少/无参的方法加了一些默认值,最后return参数最多的方法。 

原理

  • 如果没有指定leaseTime(加锁时长),则意味着让看门狗(守护线程,且该守护线程是连接级别,不是线程)管理锁的过期时间,该时间由配置文件控制,默认为30S,然后在过期时间的1/3时刻进行监听一次,线程还在则加时,加时也是走配置文件。
  • 如果指定了leaseTime,则意味着自己管理过期时间,看门狗不会介入,即不会自动续期,到了leaseTime之后,如果程序没有执行完毕,依旧会释放锁。此时,其他线程就可以继续对key加锁
  • 如果线程A加锁成功,线程B又来加锁,此时线程B会获取到线程A还有多少秒释放锁,然后线程B会通过semaphore信号量来等待一定的时间
  • 线程B在等待了一定的时间之后,会重新尝试进行加锁,加锁成功,就返回,如果失败,就重复3步

使用

  • 关于lock和trylock的使用,按场景需要进行抉择
  • 关于leaseTime是否指定,也就是说要不要使用看门狗控制过期时间,这个很难抉择, 各有利弊,如果可以自己估算业务时间,建议别用看门狗,因为看门狗存在失效或者死锁的可能,但是如果实在估算不出程序执行时间,只能冒险用看门狗了。

看门狗

Redisson中的看门狗(Watchdog)机制用于自动延长锁的持有时间,以防止锁在业务逻辑执行过程中过期。它的工作原理如下:

  • 锁续期:当一个线程获取锁后,Redisson会启动一个后台任务(看门狗),定期检查锁的持有时间,并在锁即将过期时自动延长锁的持有时间。
  • 自动释放:如果线程正常释放锁,看门狗会停止续期任务。如果线程异常退出,看门狗也会在锁过期后自动释放锁。

然而,虽然看门狗机制设计得很好,但在某些极端情况下,仍然可能出现死锁。以下是一些可能导致死锁的场景:

  • 资源竞争:在高并发环境下,多个线程竞争同一个锁,可能会导致某些线程长时间等待锁,从而增加死锁的风险。
  • 系统资源耗尽:如果系统资源(如线程池、内存)耗尽,可能会导致看门狗无法正常工作,从而引发死锁。
  • 网络问题:如果Redis服务器出现网络问题,导致看门狗无法及时续期锁,可能会导致锁过期,从而引发死锁。

为了避免这些潜在的死锁问题,可以采取以下措施:

  • 合理设置锁的超时时间:确保锁的超时时间足够长,以覆盖大部分业务逻辑的执行时间。
  • 监控和告警:监控系统的运行状态,及时发现和处理资源耗尽、网络问题等异常情况。
  • 优化业务逻辑:尽量减少锁的持有时间,避免长时间占用锁。

总结就是

  • Redisson中的看门狗机制通常不会导致死锁,但在高并发、资源耗尽或网络问题等极端情况下,仍然可能出现死锁。
  • 通过合理设置锁的超时时间、监控系统状态和优化业务逻辑,可以有效降低死锁的风险。

与setNx比较

在一定程度上redission比setNX更优秀,因为它的所有操作都是通过的lua脚本:

  • 先判断key是否存在,如果key不存在,就加锁,并且设置过期时间
  • 如果key已经存在,并且当前加锁的key是重入了,那就将key对应的加锁次数加1
  • 如果key已存在,并且当前加锁的key和线程和已加锁的不一样,无法重入,那就返回当前key的过期时间

相关文章:

Redis系列---Redission分布式锁

文章目录 类型原理使用看门狗与setNx比较 类型 使用Redission,lock的机制其实是使用了ttl,一直等ttl为0再get。无论是redission还是redis的setNx,只要是锁,都必须有加锁和释放锁两个动作,二者缺一不可,并且…...

算法打卡:第十一章 图论part05

今日收获:并查集理论基础,寻找存在的路径 1. 并查集理论基础(from代码随想录) (1)应用场景:判断两个元素是否在同一个集合中 (2)原理讲解:通过一个一维数组…...

3.《DevOps》系列K8S部署CICD流水线之部署MetalLB负载均衡器和Helm部署Ingress-Nginx

架构 服务器IP服务名称硬件配置192.168.1.100k8s-master8核、16G、120G192.168.1.101k8s-node18核、16G、120G192.168.1.102k8s-node28核、16G、120G192.168.1.103nfs2核、4G、500G操作系统:Rocky9.3 后续通过K8S部署GitLab、Harbor、Jenkins 为什么使用MetalLB 当使用云平…...

MySQL:表的约束

目录 1 空属性 2 默认值 3 列描述 4 zerofill 5 主键 6 自增长 7 唯一键 8 外键 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有…...

38.重复的子字符串

方法1: class Solution {public boolean repeatedSubstringPattern(String s) {if (s.equals("")) return false;String s2(ss).substring(1,(ss).length()-1);//去掉首尾字符return s2.contains(s);//判断是否包含s} } class Solution(object):def rep…...

Linux服务部署指南

在现代的IT基础设施中,Linux操作系统因其稳定性、安全性和灵活性而广泛用于服务部署。本文将提供一个全面的指南,介绍如何在Linux环境下部署服务,包括准备工作、部署流程、以及监控和维护。 1. 准备工作 在开始部署服务之前,确保…...

Unity中,如果你想让多个数字人轮流显示和隐藏

在Unity中,如果你想让多个数字人轮流显示和隐藏,可以通过控制它们的GameObject的激活状态 (SetActive()) 来实现。你可以创建一个简单的脚本来控制这些数字人的显示和隐藏,使用协程或者定时器来处理轮流的效果。 下面是一个基本的实现思路&a…...

【LeetCode】动态规划—删除并获得点数(附完整Python/C++代码)

动态规划—#740. 删除并获得点数 前言题目描述基本思路1. 问题定义:2. 理解问题和递推关系:3. 解决方法:4. 进一步优化:5. 小总结: 代码实现Python3代码实现Python 代码解释C代码实现C 代码解释 总结: 前言 给你一个整数数组 n u m s nums nums ,你可以对它进行一…...

利用 PostgreSQL 构建 RAG 系统实现智能问答

在现代信息检索和自然语言处理的场景中,检索增强生成 (Retrieval-Augmented Generation, RAG) 系统因其结合了知识库检索和生成模型的优势,成为了一种非常流行的智能问答方法。在这篇博文中,我将展示如何利用PostgreSQL作为向量存储数据库&am…...

Go 并发模式:扩展与聚合的高效并行

当你搭建好一个管道系统后,数据在各个阶段之间顺畅地流动,并根据你设定的操作逐步转换。这一切看起来像是一条美丽的溪流,然而,为什么有时候这个过程会如此缓慢呢? 在处理数据时,某些阶段可能会非常耗时,导致上游的阶段被阻塞,无法继续处理数据。这不仅影响了管道的整…...

【Transformers基础入门篇2】基础组件之Pipeline

文章目录 一、什么是Pipeline二、查看PipeLine支持的任务类型三、Pipeline的创建和使用3.1 根据任务类型,直接创建Pipeline,默认是英文模型3.2 指定任务类型,再指定模型,创建基于指定模型的Pipeline3.3 预先加载模型,再…...

java反射学习总结

最近在项目上有一个内部的CR,运用到了反射。想起之前面试的时候被面试官追问有没有在项目中用过反射,以及反射的原理和对反射的了解。 于是借此机会,学习回顾一下反射,以及在项目中可能会用到的场景。 Java 中的反射概述 反射&…...

探索C语言与Linux编程:获取当前用户ID与进程ID

探索C语言与Linux编程:获取当前用户ID与进程ID 一、Linux系统概述与用户、进程概念二、C语言与系统调用三、获取当前用户ID四、获取当前进程ID五、综合应用:同时获取用户ID和进程ID六、深入理解与扩展七、结语在操作系统与编程语言的交汇点,Linux作为开源操作系统的典范,为…...

1.4 边界值分析法

欢迎大家订阅【软件测试】 专栏,开启你的软件测试学习之旅! 文章目录 前言1 定义2 选取3 具体步骤4 案例分析 本篇文章参考黑马程序员 前言 边界值分析法是一种广泛应用于软件测试中的技术,旨在识别输入值范围内的潜在缺陷。本文将详细探讨…...

Spring IOC容器Bean对象管理-注解方式

目录 1、Bean对象常用注解介绍 2、注解示例说明 1、Bean对象常用注解介绍 Component 通用类组件注解,该类被注解,IOC容器启动时实例化此类对象Controller 注解控制器类Service 注解业务逻辑类Respository 注解和数据库操作的类,如DAO类Reso…...

OpenAI API: How to catch all 5xx errors in Python?

题意:OpenAI API:如何在 Python 中捕获所有 5xx 错误? 问题背景: I want to catch all 5xx errors (e.g., 500) that OpenAI API sends so that I can retry before giving up and reporting an exception. 我想捕获 OpenAI API…...

C++初阶学习——探索STL奥秘——标准库中的priority_queue与模拟实现

1.priority_queque的介绍 1.priority_queue中文叫优先级队列。优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元…...

PyTorch经典模型

PyTorch 经典模型教程 1. PyTorch 库架构概述 PyTorch 是一个广泛使用的深度学习框架,具有高度的灵活性和动态计算图的特性。它支持自动求导功能,并且拥有强大的 GPU 加速能力,适用于各种神经网络模型的训练与部署。 PyTorch 的核心架构包…...

C++ STL容器(三) —— 迭代器底层剖析

本篇聚焦于STL中的迭代器,同样基于MSVC源码。 文章目录 迭代器模式应用场景实现方式优缺点 UML类图代码解析list 迭代器const 迭代器非 const 迭代器 vector 迭代器const 迭代器非const迭代器 反向迭代器 迭代器失效参考资料 迭代器模式 首先迭代器模式是设计模式中…...

力扣416周赛

举报垃圾信息 题目 3295. 举报垃圾信息 - 力扣&#xff08;LeetCode&#xff09; 思路 直接模拟就好了&#xff0c;这题居然是中等难度 代码 public boolean reportSpam(String[] message, String[] bannedWords) {Map<String,Integer> map new HashMap<>()…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...