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

Redisson 分布式锁原理

加锁原理

image-20250307162041799

# 如果锁不存在 
if (redis.call('exists', KEYS[1]) == 0) then# hash结构,锁名称为key,线程唯一标识为itemKey,itemValue为一个计数器。支持相同客户端线程可重入,每次加锁计数器+1.redis.call('hincrby', KEYS[1], ARGV[2], 1);# 设置过期时间redis.call('pexpire', KEYS[1], ARGV[1]);# 成功获取锁返回nullreturn nil;
end ;
#如果是当前线程占有分布式锁,允许重入锁
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then# 将锁重入计数器自增1.redis.call('hincrby', KEYS[1], ARGV[2], 1);# 设置过期时间redis.call('pexpire', KEYS[1], ARGV[1]);# 成功获取锁返回nullreturn nil;
end ;
#如果获取不到锁,返回锁剩余过期时间,方便后续代码设置等待超时时间
return redis.call('pttl', KEYS[1]);

在分布式锁中,采用hash结构用来存储锁,其中大key表示表示这把锁是否存在,用小key表示当前这把锁被哪个线程持有。HINCRBY 可以在 KEYS[1](哈希键)不存在时直接创建并执行递增操作。

KEYS[1] : 锁名称

ARGV[1]: 锁失效时间

ARGV[2]: uuid + “:” + threadId; 锁的小key,客户端唯一标识

image-20250307163702718

image.png

图1处:判断获取锁是否等待(waitTime)超时,如果等待超时则直接返回获取锁失败。

图2处:如果等待未超时,则尝试订阅解锁channel。

图3处:获取ReissonLockEntry(获取成功表示订阅成功),超时时长设置为当前剩余的等待时间(waitTime)。 如果获取ReissonLockEntry超时,终止并取消订阅解锁消息channel,获取锁失败。

直到获取锁成功或者超时失败。 解锁消息广播给所有锁竞争的客户端,收到解锁消息后,客户端会有一个线程去重新竞争锁。当有解锁消息到达时,不需要恢复所有挂起的线程一起去竞争分布式锁,只需要唤醒一个线程去和集群中其它节点抢夺就可以了。这样好处是显而易见的,避免了大量的无效Redis请求,因为锁在集群中同一时刻只会有一个线程能持有。

解锁原理

# 判断锁是否为自己持有,不为自己持有则不允许解锁。
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) thenreturn nil;
end ;
# 由于支持可重入,所以这里需要判断是否完全解锁,每解一次锁重入计数器减1.
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then# 如果锁还没有完全解除,则延长锁租用时间redis.call('pexpire', KEYS[1], ARGV[2]);return 0;
else# 删除锁redis.call('del', KEYS[1]);# 广播解锁消息redis.call('publish', KEYS[2], ARGV[1]);return 1;
end ;
return nil;

watch dog原理

Redisson 的看门狗机制(WatchDog)是一种自动续期机制,旨在确保任务执行期间锁不会因超时而被误释放

  • 原理:当客户端获取到锁后,Redisson 会启动一个后台定时任务(即看门狗)。在锁的持有期间,看门狗会以默认间隔(10秒)不断地续期,延长锁的过期时间,使锁的默认过期时间始终保持为30秒。这样,只要任务未完成且客户端仍然活跃,锁就不会过期。
  • 默认行为:默认情况下,Redisson 会开启看门狗机制,无需开发者手动配置。如果不想启用看门狗机制,可以在调用 tryLock 时指定 leaseTime 参数。
  • leaseTime设置的影响:如果显式设置 leaseTime(例如通过 tryLock(waitTime, leaseTime, TimeUnit.SECONDS)),看门狗机制将不会启动。锁会在 leaseTime 到期时自动释放。当锁超时时间为 -1 时,而且获取锁成功时,会启动看门狗定时任务自动续锁。

Redisson 中,tryLock(waitTime, leaseTime, TimeUnit.SECONDS) 方法是一个尝试获取分布式锁的非阻塞方法,通过等待和设置锁的租约时间来控制锁的行为。

参数解释

  • waitTime:最大等待时间,即在尝试获取锁时,线程等待的最大时间。如果在这段时间内锁没有被其他线程释放,当前线程会放弃获取锁,返回 false
  • leaseTime:锁的租约时间,即锁的自动释放时间。如果成功获取锁后,线程在 leaseTime 时间内没有手动释放锁,锁将自动失效并释放给其他线程。这个参数用于确保锁不会一直持有,避免死锁。
  • TimeUnit:时间单位,可以设置为秒、毫秒等

img

相关文章:

Redisson 分布式锁原理

加锁原理 # 如果锁不存在 if (redis.call(exists, KEYS[1]) 0) then# hash结构,锁名称为key,线程唯一标识为itemKey,itemValue为一个计数器。支持相同客户端线程可重入,每次加锁计数器1.redis.call(hincrby, KEYS[1], ARGV[2], 1);# 设置过期时间redis.call(pexpi…...

高频SQL50题 第四天 | 1251. 平均售价、620. 有趣的电影、1075. 项目员工 I、1633. 各赛事的用户注册率

知识点导览:日期大小比较;ifnull(字段,默认值)函数;取余操作;字符串比较like;逆序desc 1251. 平均售价 题目链接:https://leetcode.cn/problems/average-selling-price/description/?envTypest…...

【STM32】SPI通信外设硬件SPI读写W25Q64

SPI通信协议和W25Q64存储器芯片解读笔记: 【STM32】SPI通信协议&W25Q64Flash存储器芯片(学习笔记)-CSDN博客 SPI通信外设 SPI外设简介 STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能&…...

风暴潮、潮汐潮流模拟:ROMS模型如何精准预测海洋现象?

海洋数值模拟的崛起与 ROMS 的关键角色 🌊在海洋科学的浪潮中,海洋数值模拟正以迅猛之势崛起,成为科研与实际应用领域不可或缺的利器。ROMS(Regional Ocean Modeling System)作为其中的佼佼者,凭借其高效、…...

Spring JDBC Template与事务管理:基于XML与注解的实战指南

摘要 本文深入解析Spring JDBC Template与事务管理的核心技术,结合XML配置与注解方式两种主流方案,通过转账案例完整演示数据库操作与事务管理的最佳实践。文章涵盖JDBC Template的核心用法、事务配置语法、常见问题及性能优化建议,帮助开发…...

【Keil5-开发技巧】

Keil5-开发技巧 ■ Keil5利用AStyle插件格式化代码第一步:下载AStyle插件第二步:添加AStyle插件第三步:AStyle插件介绍■ 一键转UTF-8编码■ Keil5利用AStyle插件格式化代码 第一步:下载AStyle插件 AStyle下载 第二步:添加AStyle插件 解压后 astyle-3.6.7-x64 在重命…...

Uniapp:基于 Vue.js 的高效跨平台开发框架

Uniapp 介绍 Uniapp(全称:Universal Application)是一款基于 Vue.js 的跨平台开发框架,由 DCloud 公司开发和维护。它允许开发者使用一套代码同时构建运行在多个平台(如 iOS、Android、Web、小程序、快应用等&#xf…...

form 表单内容序列化成一个字符串

html <form id"form1" action"http://localhost:8080/xxx" method"post"> <p >关键字1&#xff1a; <input type "text" name"keyword1" /></p> <p >关键字2&#xff1a; <input t…...

电脑上不了网普通用户排除方法

1&#xff1a;首先通过电脑的运行/CMD/ipconfig /all 命令查看电脑的ip地址是否正常如图&#xff1a; 2&#xff1a;在命令行中运行&#xff1a;ping 127.0.0.1 如图则正常&#xff0c;否则要重新安装网卡驱动 程序。 3&#xff1a;用ping命令&#xff0c;ping一下同网段的电…...

【C#】WinForm自定义控件及窗体

前言 WinForm&#xff08;Windows Forms&#xff09;是Microsoft.NET框架中的技术&#xff0c;用于开发Windows桌面应用程序。它提供了一套丰富的控件和组件。通过拖放控件、编写事件处理程序等方式快速构建用户界面。 通过属性窗口定制这些控件的外观和行为。 通过数据绑定&am…...

基于虚拟知识图谱的语义化决策引擎

在数字化转型浪潮中&#xff0c;企业数据资产的价值释放面临两大挑战&#xff1a;海量异构数据的整合困局与业务-技术语义鸿沟。本文解析飞速创软灵燕智能体平台的创新解决方案——通过构建业务语义驱动的虚拟知识图谱系统&#xff0c;实现企业数据的智能认知与决策赋能。 一、…...

七天免登录 为什么不能用seesion,客户端的http请求自动携带cookei的机制(比较重要)涉及HTTP规范

如果是七天免登录,和session肯定没关系,因为session不能持久化,主要是客户端一旦关闭,seesion就失效了/// 所以必须是能持久化的&#xff0c;这就清晰了&#xff0c;要莫在的服务器保存&#xff0c;要摸在客户端设置 cook机制 1. 使用Cookie实现七天免登录 前端&#xff08;登…...

HarmonyOS:@AnimatableExtend 装饰器自学指南

在最近的项目开发中&#xff0c;我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中&#xff0c;我发现了 AnimatableExtend 装饰器&#xff0c;它为实现动画效果提供了一种非常灵活且强大的方式。然而&#xff0c;在学习这个装饰器的过程中&#xff0c;我发现相关的…...

主流NoSQL数据库类型及选型分析

在数据库领域&#xff0c;不同类型的数据库针对不同场景设计&#xff0c;以下是四类主流NoSQL数据库的对比分析&#xff1a; 一、核心特性对比 键值数据库&#xff08;Key-Value&#xff09; 数据模型&#xff1a;简单键值对存储 特点&#xff1a;毫秒级读写、高并发、无固定…...

kubernetes|云原生|kubeadm-1.25.7集群单master+外部etcd集群+kubeadm-init+cri-docker文件形式快速部署

一、 前言和写作原因 本文做一个kubernetes集群部署记录&#xff0c;实在是部署的东西太多了&#xff0c;害怕忘记&#xff0c;kubernetes集群的部署又细节比较多&#xff0c;因此&#xff0c;在这里做一个尽量详细的记录 三个VMware虚拟机&#xff0c;IP分别为192.168.123.…...

Qt 导入TagLib库

文章目录 0. 前言和环境介绍1. 下载TagLib2. 下载zlib3. 修改.pro文件4. 测试代码 0. 前言和环境介绍 最近在使用Qt写一个播放器&#xff0c;需要解析mp3文件&#xff0c;于是研究了一下如何导入TagLib库 Qt构建套件:Desktop Qt6.8.2 MinGW64-bit Qt Creator安装目录: D:\bit…...

新能源汽车充换站如何实现光储充一体化管理?

长三角某换电站光伏板晒到发烫&#xff0c;却因电网限电被迫切机&#xff1b;北京五环充电站每月多缴6万超容费&#xff1b;深圳物流车充电高峰排队3小时...当95%的充换站深陷“用不起绿电、扛不住扩容、算不清碳账”困局&#xff0c;安科瑞用一组真实数据撕开行业潜规则&#…...

【数据分享】2000—2024年我国省市县三级逐年归一化植被指数(NDVI)数据(年平均值/Shp/Excel格式)

之前我们分享过2000-2024年我国逐年的归一化植被指数&#xff08;NDVI&#xff09;栅格数据&#xff0c;该逐年数据是取的当年月归一化植被指数&#xff08;NDVI&#xff09;的年平均值。&#xff01;该数据来源于NASA定期发布的MOD13A3数据集&#xff01;很多小伙伴拿到数据后…...

【leetcode题解】链表

目录 链表 两数相加 两两交换链表中的节点 重排链表 合并 K 个升序链表&#xff08;困难&#xff09; K 个一组翻转链表 链表 1. 常用技巧 画图&#xff01;&#xff01;&#xff01;&#xff08;直观形象&#xff0c;便于我们理解&#xff09;引入虚拟“头”节点&#xf…...

本地部署Dify 添加Ollama模型DeepSeek

1、准备工作 本地ollama 加载DeepSeek。 安装并登录Dify。 2、添加Ollama模型服务商 在设置-》模型服务上里添加Ollama模型服务商&#xff0c;也叫插件。 3、添加DeepSeek 使用终端命令 ollama list查询deepseek名称&#xff0c;如deepseek-r1:14b。 在Ollama插件冲添加…...

QEMU源码全解析 —— 块设备虚拟化(7)

接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(6) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 特此致谢! QEMU初始化阶段的块设备虚拟化 从模板生成类和类的实例化 上一回在讲解QEMU中类继承…...

图论 | 岛屿数量(深搜,广搜)

岛屿数量 acm模式&#xff1a;99.岛屿数量 核心代码模式&#xff1a; 200. 岛屿数量 思路 遍历grid&#xff0c;如果它是1&#xff0c;则通过bfs/dfs将这个小岛的grid变为0 dfs def dfs(grid,i,j):if i<0 or j<0 or i>len(grid) or j>len(grid[0]):returnif g…...

iOS:GCD信号量、同步、异步的使用方法

信号量的详细用法&#xff0c;可以用此方法进行队列管理 -(void)dispatchSignal{//crate的value表示&#xff0c;最多几个资源可访问dispatch_semaphore_t semaphore dispatch_semaphore_create(3);dispatch_queue_t quene dispatch_get_global_queue(DISPATCH_QUEUE_PRIORI…...

MSP430 Proteus 仿真作品

https://www.dong-blog.fun/post/1998 1 、 电子万年历&#xff08;采用 DS1302 及 及 TC72 等芯片&#xff09; 基本要求&#xff1a; 可显示年、月、日、星期、时、分、秒&#xff1b; 有温度显示功能。 发挥部分&#xff1a; 可调节时间和日期&#xff1b; 有农历显示功能 &…...

Windows打开ftp局域网共享

前提是windows已经设置好开机账号密码了&#xff0c;否则教程不适用 第一先打开电脑ftp共享配置 点击保存即可 2.设置要共享到其他电脑的文件路径&#xff08;如果你要共享整个盘你就设置整个盘&#xff0c;如果是共享盘中某文件就设置某文件&#xff0c;这里是某文件&#x…...

基于HTML的邮件发送状态查询界面设计示例

以下是一个基于HTML的邮件发送状态查询界面设计示例&#xff0c;结合筛选功能、状态展示和重新发送操作&#xff0c;采用Bootstrap框架实现响应式布局&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"&…...

聊聊langchain4j的MCP

序 本文主要研究一下langchain4j对Model Context Protocol (MCP) 的支持 MCP MCP协议规定了两种传输方式&#xff1a; HTTP&#xff1a;客户端请求一个SSE&#xff08;Server-Sent Events&#xff09;通道以从服务器接收事件&#xff0c;然后通过HTTP POST请求发送命令。这…...

我爱学算法之——滑动窗口攻克子数组和子串难题(中)

学习算法&#xff0c;继续加油&#xff01;&#xff01;&#xff01; 一、将 x 减到 0 的最小操作数 题目解析 来看这一道题&#xff0c;题目给定一个数组nums和一个整数x&#xff1b;我们可以在数组nums的左边或者右边进行操作&#xff08;x减去该位置的值&#xff09;&#…...

从零开始上手huggingface

1. 环境配置 # git 安装&#xff1a;https://git-scm.com/ # git lfs安装&#xff1a;https://git-lfs.com git lfs install # huggingface-cli 安装&#xff1a;https://huggingface.co/docs/hub/index pip install huggingface_hub2. 网站直接下载模型 可能会中断&#xff…...

MySQL 死锁问题分析与解决方案

**** 一、死锁原因分析 死锁通常由以下场景引发&#xff1a; 事务执行顺序不一致&#xff1a;多个事务以不同顺序访问相同资源。索引缺失&#xff1a;全表扫描导致行锁升级为表锁。长事务或大事务&#xff1a;长时间持有锁资源&#xff0c;增加冲突概率。隔离级别设置&#x…...