Redisson 实现分布式锁源码浅析
大家好,我是此林。
今天来分享Redisson分布式锁源码。还是一样,我们用 问题驱动 的方式展开讲述。
1. redis 中如何使用 lua 脚本?
Redis内置了lua解释器,lua脚本有两个好处:
1. 减少多次Redis命令的网络传输开销。(当然也可以使用pipline命令)
2. lua脚本所有命令能保证原子性,隔离性(Redis单线程),失败回滚
综上所述,Redis中如果想要实现事务操作,可以使用lua脚本。
Redis 本身也可以使用 MULTI + WATCH乐观锁 来实现,但是它只能保证命令执行的顺序性,无法保证失败回滚,无法保证原子性。
所以,一般推荐使用 lua 脚本。
使用案例:
现在我们要去执行redis命令:
HSET info name john
1. lua脚本
local hash_key = KEYS[1] -- 哈希结构的键名(外部传入)
local key = ARGV[1] -- 哈希字段(外部传入)
local value = ARGV[2] -- 哈希字段值(外部传入)return redis.call('HSET', hash_key, key, value)
因为KEYS[1]、ARGV[1]等都是外部传入,所以可以简化。
return redis.call('HSET', KEYS[1], ARGV[1], ARGV[2])
redis.call()就是执行redis命令。
2. redis 命令
EVAL "return redis.call('HSET', KEYS[1], ARGV[1], ARGV[2])" 1 info name john
这里的1代表传入一个key。
2. 如何使用Redisson?
这里的
boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
是获取锁,第一个1表示:锁超时等待时间,在1秒内会不断重试获取锁,直到获取到。
第二个10表示:锁释放时间,为10秒(防止java服务获取到锁后,突然宕机,导致redis锁永远不会被释放,避免造成死锁问题。)
3. Redisson源码?
3.1. Redisson如何实现锁重入?
其实归根结底,就是这段代码。Redisson本质上是使用hash结构来标志锁的,可能我们经常听到说用setnx命令来实现分布式锁,但是setnx无法实现锁的重入。
所以Redisson用 hash(计数) + lua脚本(原子性)实现可重入分布式锁。
先说明下参数:
KEYS[1]:hash结构的键名,也就是我们之前手动指定的 anylock
ARGV[1]:锁的释放时间
ARGV[2]:hash结构的字段的键名,UUID:线程id
我们直接去看redis:
anyLock这个hash结构里,
有字段的key为c3341b71-6edd-4db8-b626-9135cf727fd4:1,value为1
了解了锁的结构后,我们再来看lua脚本。
一图胜千言,总的来说,
第一个if:处理线程第一次获取锁
第二个if:处理线程重入获取锁
最后:发现锁已经被占有,返回剩余ttl(过期时间)。
3.2. 如果抢锁失败呢?
之前说的锁的设置,其实就是图中框起来的方法里的实现。
接下来,如果ttl为null,抢锁成功了,直接返回true。
如果ttl不为null,说明抢锁失败了,会去计算等待时间是否充足。
这里的等待时间就是我们之前手动设置的1秒钟。
如果锁等待时间还充足,那么执行它会去用pub-sub机制去 订阅锁释放事件。(避免轮询 Redis 造成的性能损耗。)
如果订阅超时,触发失败回调,返回false。
那么订阅成功了之后呢?会再次尝试抢锁。
还不行,那只能信号量挂起,具体通过 Semaphore
(getLatch()
)挂起当前线程,等待锁释放的 Pub/Sub 通知。
总结一下抢锁流程:
抢锁成功,直接返回;抢锁失败,pub/sub机制订阅锁释放事件,通过信号量挂起线程,直到收到锁释放的消息才被唤醒。
3.3. 解锁流程是怎么样的?
看下图。本质还是那一段lua脚本。
先看下锁是不是线程自己的,不是的话直接返回null。
如果锁是自己的,计数器减1。
如果减1操作后还大于0,说明重入的还没完,刷新锁的超时释放时间。
如果减1后小于等于0,直接删除,发布锁删除事件。
- 返回nil表示锁不属于当前线程,应抛出异常。
- 返回0表示锁未完全释放,仅更新了过期时间。
- 返回1表示锁已释放,并发布事件。
3.4. Redisson的看门狗机制?
看门狗主要用于 解决锁的自动续期问题,避免因业务执行时间过长导致锁超时自动释放。
注意一点:如果我们显式指定了leaseTime参数,看门狗机制就不会生效。这时候锁的过期时间由用户控制。
像我们之前手动指定了锁释放时间10秒,它就不会走看门狗机制,Redisson默认锁释放时间是30秒。(见下图,单位毫秒)
在scheduledExpirationRenewal方法里,其实就是用了netty的时间轮进行定时任务调度,每隔10秒重置锁时间为30秒,直到业务执行结束。
每次续期成功后,会递归调用 renewExpiration()
,形成 无限续期链,直到锁被释放(主动释放或者客户端宕机)。
关于 时间轮,这是一种高效的定时任务调度设计。
感兴趣的朋友可以去看下之前写的文章:
时间轮:XXL-JOB 高效、精准定时任务调度实现思路分析_xxljob fasttriggerpool slowtrigger-CSDN博客
至于为什么不使用ScheduledThreadPoolExecutor?
是因为ScheduledThreadPoolExecutor的底层结构:基于优先级队列(堆实现)。插入任务的时间复杂度 O(log n)
,每次插入需调整堆结构。
使用时间轮插入任务的时间复杂度为 O(1)
,直接哈希到时间槽(Bucket),并且支持同一槽内任务批量触发。
3.5. Redisson怎么解决死锁的?
主要就是设置了锁的超时释放时间,客户端宕机了会自动超时释放。
然后还有一点支持重入,如果同一个线程两次去获取锁,因为支持重入,第二次就不会阻塞等待自己释放锁了。
至于说看门狗机制会无限续期,客户端宕机了就续期不了,不会导致死锁。
那你说:业务要是无限阻塞,永远执行不完呢?
这个也不大可能,为什么业务会无限阻塞?这个时候肯定需要人工介入去排查问题了。
今天的分享就到这里了,我是此林。
关注我吧,带你看不一样的世界!
相关文章:
Redisson 实现分布式锁源码浅析
大家好,我是此林。 今天来分享Redisson分布式锁源码。还是一样,我们用 问题驱动 的方式展开讲述。 1. redis 中如何使用 lua 脚本? Redis内置了lua解释器,lua脚本有两个好处: 1. 减少多次Redis命令的网络传输开销。…...
机试准备第17天
今天进入图论的学习。图论只考察初试学过的算法,一般都是模版题。常见考点有图相关的数据结构——邻接表法,图的遍历 BFS DFS 并查集,单源最短路径迪杰斯特拉。图由顶点和边构成,度用来说明该顶点邻接边的数量情况。权值说明了边的…...
ABAP语言的动态编程(4) - 综合案例:管理费用明细表
本篇来实现一个综合案例:管理费用明细表。报表在实际项目中,也有一定的参考意义,一方面展示类似的报表,比如管理费用、研发费用等费用的明细,使用业务比较习惯的展示格式;另一方面正好综合运用前面学习的动…...
不像人做的题————十四届蓝桥杯省赛真题解析(上)A,B,C,D题解析
题目A:日期统计 思路分析: 本题的题目比较繁琐,我们采用暴力加DFS剪枝的方式去做,我们在DFS中按照8位日期的每一个位的要求进行初步剪枝找出所有的八位子串,但是还是会存在19月的情况,为此还需要在CHECK函数…...
R语言零基础系列教程-01-R语言初识与学习路线
代码、讲义、软件回复【R语言01】获取。 R语言初识 R是一个开放的统计编程环境,是一门用于统计计算和作图的语言。“一切皆是对象”,数据、函数、运算符、环境等等都是对象。易学,代码像伪代码一样简洁,可读性高强大的统计和可视…...
即时通讯平台测试报告
1.项目概述 项目名称:即时通讯平台 版本号:V1.0.0 测试周期:2025年2月25日--2025年3月15日 测试目标:验证核心功能(登录、注册、消息收发、用户管理、群组功能等)的稳定性和性能指标。 2. 测试范围 功…...
蓝桥杯单片机内存爆了怎么办
蓝桥杯单片机内存爆了怎么办 文章目录 蓝桥杯单片机内存爆了怎么办一、参考文章二、内存区3、keil中的体现4、分配原则5、使用示例 一、参考文章 文章1 文章2 文章3 文章4 二、内存区 1 KB(千字节) 1024 B(字节) B代表Byte,1Byte8bit,一个字节8位 …...
一周热点:微软攻克语音输入、文本输出难题-Phi-4-multimodal
微软Phi-4-multimodal模型是人工智能领域的一个重要进展,它标志着微软在多模态人工智能技术上的突破。以下是对该模型的详细解释: 模型概述 微软Phi-4-multimodal是一个能够同时处理文本、图像和语音的多模态大型语言模型。它通过创新的架构和训练方法,实现了在不同模态之间…...
量化交易学习笔记02:双均线策略
双均线策略示例 个股:中国平安 回测日期:2022-5-1至2023-5-1 短均线:5天 长无线:10天 代码: def initialize(context):# 初始化此策略# 设置我们要操作的股票池, 这里我们只操作一支股票# """标的&qu…...
【WRF-Urban】使用 CGLC-MODIS-LCZ_100m 数据集运行 WRF 时的城市参数化问题
在 WRF 中,LCZ 通过 URBPARM_LCZ.TBL 进行配置,但如果 FRC_URB2D 变量缺失,WRF 会回退到默认的 URBPARM.TBL。 主要问题概述 WRF-Model-cglc-modis-lcz_100m dataset " WARNING, THE URBAN FRACTION WILL BE READ FROM URBPARM.TBL USING DEFAULT URBAN MORPHOLOGY&q…...
Selenium 自动化测试学习总结
大概了解一下即可,现在主要用的自动化工具是 playWright,它可以录制操作。 selenium是老款自动化测试工具,仍有很多可取之处。 安装: pip install selenium即可。然后下载浏览器的驱动包,注意不是浏览器!…...
开源通义万相本地部署方案,文生视频、图生视频、视频生成大模型,支持消费级显卡!
开源通义万相本地部署方案,文生视频、图生视频、视频生成大模型,支持消费级显卡! 万相2.1开源 近日,大模型万相2.1(Wan)重磅开源,此次开源采用Apache2.0协议,14B和1.3B两个参数规格…...
Suno的对手Luno:AI音乐开发「上传参考音频 - 方式一:通过二进制流的方式」 —— 「Luno Api系列|AI音乐API」第11篇
导读 今天来看下Luno Api的上传参考音频 - 方式一:通过二进制流的方式。 参考文件,主要是用于在创作的过程中,希望AI参考这个音乐的曲风和声音来进行创作,那么可以通过上传参考音乐来进行实现。 申请和使用 「已经有API的&…...
微信小程序刷题逻辑实现:技术揭秘与实践分享
页面展示: 概述 在当今数字化学习的浪潮中,微信小程序以其便捷性和实用性,成为了众多学习者刷题备考的得力工具。今天,我们就来深入剖析一个微信小程序刷题功能的实现逻辑,从代码层面揭开其神秘面纱。 小程序界面布局…...
巴耶赫利专业俄语外贸网站建设
巴耶赫利是专业俄语外贸网站建设与俄语搜索引擎Yandex SEO优化服务商。巴耶赫利致力于帮助中国品牌出海俄罗斯,打开俄罗斯市场,提升品牌在俄罗斯的知名度和美誉度。 以下是对巴耶赫利相关服务的详细介绍: 一、巴耶赫利专业俄语外贸网站建设…...
每日Attention学习25——Multi-Scale Attention Fusion
模块出处 [TCSVT 24] [link] [code] DSNet: A Novel Way to Use Atrous Convolutions in Semantic Segmentation 模块名称 Multi-Scale Attention Fusion (MSAF) 模块作用 双级特征融合 模块结构 模块思想 MSAF的主要思想是让网络根据损失学习特征权重,允许模型…...
前端学习记录:解决路由缓存问题
问题描述:响应路由参数的变化,使用带有参数的路由时需要注意的是,当用户从 /users/johnoy 导航到 /users/jolyne 时,相同的组件实例将会被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得…...
VSTO(C#)Excel开发10:启动和卸载顺序 事件处理 监视变化
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
代码随想录Day16
Day16 二叉树part06 LeetCode 530.二叉搜索树的最小绝对差 题目描述 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其数值等于两值之差的绝对值。 示例 输入:root [4,2,6,1,3] 输出&…...
第15章:ConvNeXt图像分类实战:遥感场景分类【包含本地网页部署、迁移学习】
目录 1. ConvNeXt 模型 2. 遥感场景建筑识别 2.1 数据集 2.2 训练参数 2.3 训练结果 2.4 本地部署推理 3. 下载 1. ConvNeXt 模型 ConvNeXt是一种基于卷积神经网络(CNN)的现代架构,由Facebook AI Research (FAIR) 团队在2022年提出。…...
LinuX---Shell脚本创建和执行
概述: 它是一个命令行解释器,接收应用程序/用户命令,然后调用操作系统内核。 Shell还是一个功能强大的编程语言,易编写、易调试、灵活性强。 Linux提供的Shell解析器有 atguiguubuntu:~$ cat /etc/shells # /etc/shells: valid …...
django+vue3实现前后端大文件分片下载
效果: 大文件分片下载支持的功能: 展示目标文件信息提高下载速度:通过并发请求多个块,可以更有效地利用网络带宽断点续传:支持暂停后从已下载部分继续,无需重新开始错误恢复:单个块下载失败只…...
KY-038 声音传感器如何工作以及如何将其与 ESP32 连接
想为您的项目赋予声音感!然后跟着做,因为在这个项目中,我们将连接一个声音传感器,用它构建一些有趣的项目。我们使用的 KY-038 声音传感器使用电容式麦克风来检测声波,这为我们提供了稳定性和可靠性的完美平衡。因此,在本文中,我们决定将 KY-038 传感器与 ESP32 连接,并…...
深入剖析二分查找的延伸:在排序数组中查找元素的第一个和最后一个位置
深入剖析二分查找的延伸:在排序数组中查找元素的第一个和最后一个位置 引言 二分查找,作为算法界的“常青树”,以其高效性和简洁性备受青睐。然而,许多初学者仅限于使用它查找单个元素,而对其进阶应用知之甚少。今天…...
UE5中 Character、PlayerController、PlayerState、GameMode和GameState核心类之间的联动和分工·
1. GameMode 与 GameState 关系描述 GameMode:定义游戏规则和逻辑,控制游戏的开始、进行和结束。GameState:存储和同步全局游戏状态,如得分、时间、胜利条件等。 联动方式 GameMode初始化GameState:GameMode在游戏…...
使用Python获取并操作1688自定义API接口
在电子商务领域,1688作为国内领先的B2B平台,提供了丰富的API接口,允许开发者获取商品信息、店铺信息等。其中,custom接口允许开发者进行自定义操作,获取特定的数据。本文将详细介绍如何使用Python调用1688的custom接口…...
【AI】现代人工智能技术的应用与发展
引言 人工智能(AI)已经深入到我们生活的各个方面,涉及医疗、教育、交通、金融等众多领域。随着技术的不断发展,AI的应用和潜力也变得愈加广泛。本文将详细介绍人工智能的应用领域,探讨未来的发展趋势,并通…...
小程序渲染之谜:如何解决“加载中...”不消失的 Bug(glass-easel)
🎉 小程序渲染之谜:如何解决“加载中…”不消失的 Bug 🎉 引言 在小程序开发中,渲染问题总能让人抓狂。😫 这次,我遇到了一个奇怪的 bug:产品详情页的内容已经正常显示,但页面却一…...
C语言结构体全面解析 | 从入门到精通
📚 C语言结构体全面解析 | 从入门到精通 整理:算法练习生| 转载请注明出处 📑 目录 结构体的定义与使用结构体变量的参数传递结构体数组结构体指针typedef关键字结构体初始化 1️⃣ 结构体的定义与使用 为什么需要结构体? 当…...
Trae与Builder模式初体验
说明 下载的国际版:https://www.trae.ai/ 建议 要选新模型 效果 还是挺不错的,遇到问题反馈一下,AI就帮忙解决了,真是动动嘴(打打字就行了),做些小的原型效果或演示Demo很方便呀ÿ…...
麒麟服务器操作系统QT系列软件工具手册
QtCreator****功能介绍 QtCreator 概述 Qt Creator是跨平台的 Qt IDE, Qt Creator 是 Qt 被 [Nokia](https://baike.baidu.com/item/Nokia/264012" /t “_blank) 收购后推出的一款新的轻量级[集成开发环境](https://baike.baidu.com/item/集成开发环境/298524” /t “_…...
【HeadFirst系列之HeadFirstJava】第18天之深入理解原型模式:从问题到解决方案(含 Java 代码示例)
深入理解原型模式:从问题到解决方案(含 Java 代码示例) 在软件开发中,我们经常需要创建对象,而有些对象的创建成本较高或者结构较为复杂。如何在不破坏封装的前提下,高效地创建对象? 这正是**原…...
JetsonOrin源码安装部署PaddlePaddle
Jetson Orin 源码安装部署Paddle 部署环境 系统架构: Arm CUDA: 11.4 cmake: 3.18.0 python:3.8 注意环境中的版本问题,之前装onnxruntime的时候cmake被升级到了3.31.0,但是编译Paddle时会报错,因此特意降级回了官方推荐的3.18.0 具体环…...
入门到入土,Java学习 day20(多线程下)
void wait() 当前线程等待,直到被其他线程唤醒 void notify() 随机唤醒单个线程 void notifyAll() 唤醒所有线程 阻塞队列 在测试方法中创建带锁队列,然后在对象类中也创建队列但是不赋值,用构造方法将测试方法中的对象赋值 然后用put和t…...
【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解
活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!…...
栈(LIFO)算法题
1.删除字符串中所有相邻的重复字符 注意,我们需要重复处理,而不是处理一次相邻的相同元素就结束了。对示例来说,如果只进行一次处理,结果为aaca,但是处理之后又出现了相邻的重复元素,我们还得继续处理&…...
印章/公章识别:PaddleX下的“Seal-Recognition”模型
最近做项目需要对印章进行识别,并提取其中的印章文字,又不希望这个模型太大,还要方便部署,于是乎这个模型是个不错的选择。 一、模型简介 “Seal-Recognition”模型是PaddleX旗下的一款模型(PaddleX 是基于飞桨框架构…...
从LLM出发:由浅入深探索AI开发的全流程与简单实践(全文3w字)
文章目录 第一部分:AI开发的背景与历史1.1 人工智能的起源与发展1.2 神经网络与深度学习的崛起1.3 Transformer架构与LLM的兴起1.4 当前AI开发的现状与趋势 第二部分:AI开发的核心技术2.1 机器学习:AI的基础2.1.1 机器学习的类型2.1.2 机器学…...
DeepSeek入门宝典——行业应用篇
大家好,我是吾鳴。 今天吾鳴要给大家分享一份由51CTO智能研究院出品的DeepSeek报告——《DeepSeek入门宝典——行业应用篇》。这份报告主要从DeepSeek核心能力、行业赋能与应用案例、合作伙伴与生态建设和学习资料与体系化方案做了详细的介绍,报告一共有…...
K8S学习之基础三十一:k8s中RBAC 的核心概念
Kubernetes (k8s) 中的 RBAC(Role-Based Access Control,基于角色的访问控制)是一种用于管理用户和服务账户对集群资源访问权限的机制。RBAC 允许管理员通过定义角色(Role)和角色绑定(RoleBindingÿ…...
JAVA数据库技术(一)
JDBC 简介 JDBC(Java Database Connectivity)是Java平台提供的一套用于执行SQL语句的Java API。它允许Java程序连接到数据库,并通过发送SQL语句来查询、更新和管理数据库中的数据。JDBC为不同的数据库提供了一种统一的访问方式,使…...
【Agent】OpenManus-Flow组件详细分析
1. Flow架构概述 OpenManus 的Flow组件实现了一个灵活的工作流管理系统,主要用于协调多个智能体的协作,以完成复杂任务。Flow组件的核心是基于计划的执行模型,它将任务分解为一系列步骤,然后逐步执行这些步骤,直到任务…...
MySQL环境安装详细教程(Windows/macOS/Linux)
摘要:本文详细介绍了在Windows、macOS和Linux三大操作系统下安装MySQL数据库的完整流程,帮助开发者快速搭建本地MySQL环境。 一、MySQL安装前准备 官网下载 访问MySQL官网 → 选择"Downloads" → 选择"MySQL Community (GPL) Downloads&…...
【人工智能基础2】人工神经网络、卷积神经网络基础、循环神经网络、长短时记忆网络
文章目录 三、人工神经网络1. 神经元感知模型2. 神经网络模型3. 学习规则:修改神经网络的权重和偏置反向传播算法(BP)优化器 - 梯度下降法 四、卷积神经网络基础(CNN)1. 基本原理2. 计算过程 五、循环神经网络(RNN&…...
如何查看windows系统的硬件环境(附方法
方法一:使用命令指示符查询 在“开始”菜单中搜索:命令指示符,并以管理员身份打开, 输入:systeminfo,就可以查看硬件、CPU、处理器等详细内容 systeminfo 方法二:在资源监视器中查看 按住 “…...
基于树莓派的水果分类系统(论文+源码)
针对小型农户的在水果加工销售环节中的分类需求,本文设计并实现了基于树莓派的视觉识别分类系统。本章根据所选水果的具体情况,简述系统各模块的实现方法,设计树莓派的程序算法,并选择合适的器件型号,开发所用的辅助工…...
Gemini Robotics:将人工智能带入物理世界
25年3月来自谷歌的技术报告“Gemini Robotics: Bringing AI into the Physical World”。 大型多模态模型的最新进展,已使数字领域出现卓越的通才能力,但将其转化为机器人等物理智体仍然是一项重大挑战。一般有用的机器人需要能够理解周围的物理世界&am…...
2.5[frontEnd]
requestAnimationFrame 是 浏览器原生 API,定义在 window 对象中,属于 Web API 的一部分。无需任何导入即可直接使用,其类型定义包含在 TypeScript 标准库中。 React 组件挂载时执行该 useEffect 初始化节流计时器 lastEmit 和 25ms 触发间隔…...
【动手学深度学习】#2线性神经网络
主要参考学习资料: 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李牧学AI 目录 2.1 线性回归2.1.1 线性回归的基本元素线性模型损失函数解析解随机梯度下降 2.1.3 最大似然估计 2.2 线性回归从零开始实现2.2.1 生成数据集2.2.2 读取数…...
C语言动态内存管理(上)
欢迎拜访:雾里看山-CSDN博客 本篇主题:C语言动态内存管理(上) 发布时间:2025.3.16 隶属专栏:C语言 目录 为什么需要动态内存管理静态分配的局限性动态分配的优势 动态内存函数malloc函数介绍函数使用 free函数介绍函数使用 calloc…...