Redisson是如何实现分布式锁的?

Redisson 如何实现分布式锁?(核心原理与思考)

Redisson 是一个功能强大的 Redis 客户端,它提供了许多分布式对象和服务,其中就包括分布式锁。Redisson 的分布式锁是基于 Redis 的 Lua 脚本实现的,这保证了操作的原子性。

我们来一步步拆解 Redisson 锁的实现原理

4.1 最基础的 Redis 锁(存在的问题)

如果只用 SETNXDEL

  1. 加锁: SETNX mylock_key my_client_id
    • my_client_id 是一个唯一标识,比如 UUID,用来标识是哪个客户端加的锁。
  2. 解锁: DEL mylock_key

问题:

  • 死锁: 如果客户端加锁后,还没来得及 DEL 就宕机了,那么 mylock_key 永远不会被删除,其他客户端就永远拿不到锁了。
  • 误删: 如果客户端A加锁,但因为网络延迟等原因,锁过期了(被Redis自动删除了),然后客户端B加锁成功。此时客户端A恢复,执行 DEL mylock_key,它删除了客户端B的锁!
4.2 Redisson 的改进:过期时间 + 唯一ID + Lua 脚本

Redisson 解决了上述问题,它的核心思想是:

  1. 加锁时设置过期时间: 避免死锁。
  2. 加锁时设置唯一ID: 避免误删。
  3. 使用 Lua 脚本: 保证加锁和解锁操作的原子性。

Redisson 加锁的 Lua 脚本(简化版):

-- KEYS[1]: 锁的名称 (e.g., "myLock")
-- ARGV[1]: 锁的过期时间 (e.g., 30000 毫秒)
-- ARGV[2]: 客户端的唯一ID (e.g., UUID + 线程ID)-- 如果锁不存在,或者锁是当前客户端加的
if redis.call('exists', KEYS[1]) == 0 or redis.call('hexists', KEYS[1], ARGV[2]) == 1 then-- 设置锁,并设置过期时间-- HINCRBY: 将哈希表中字段的值增加指定增量。这里是记录重入次数redis.call('hincrby', KEYS[1], ARGV[2], 1);redis.call('pexpire', KEYS[1], ARGV[1]); -- 设置过期时间 (毫秒)return nil; -- 表示加锁成功
end;
return redis.call('pttl', KEYS[1]); -- 返回锁的剩余过期时间,表示加锁失败

Redisson 解锁的 Lua 脚本(简化版):

-- KEYS[1]: 锁的名称
-- ARGV[1]: 客户端的唯一ID-- 如果锁不存在,或者不是当前客户端加的锁
if redis.call('exists', KEYS[1]) == 0 or redis.call('hexists', KEYS[1], ARGV[1]) == 0 thenreturn nil; -- 表示解锁失败或锁不存在
end;-- 减少重入次数
local counter = redis.call('hincrby', KEYS[1], ARGV[1], -1);
-- 如果重入次数归零,说明完全释放了锁
if counter > 0 then-- 重新设置过期时间redis.call('pexpire', KEYS[1], ARGV[2]); -- ARGV[2] 是新的过期时间return 0; -- 表示锁还在,只是重入次数减少
else-- 重入次数归零,删除锁redis.call('del', KEYS[1]);return 1; -- 表示锁已完全释放
end;
return nil;

思考:为什么用 Hash 类型?

  • HINCRBY:这实现了可重入锁。同一个客户端(同一个线程)可以多次获取同一个锁,每次获取都会增加哈希表中对应字段的值(重入次数)。释放锁时,每次减少重入次数,直到为0才真正释放锁。
  • 哈希表的字段是客户端的唯一ID,值是重入次数。
  1. 锁的类型:
    • 可重入锁 (Reentrant Lock): 最常用,上面已解释。
    • 公平锁 (Fair Lock): 保证获取锁的顺序。
    • 联锁 (MultiLock): 同时获取多个 Redis 实例上的锁,只要有一个实例加锁失败,所有已加的锁都会被释放。用于解决 Redis 单点故障问题。
    • 红锁 (RedLock): Redisson 实现了 Redis 官方推荐的 RedLock 算法。它需要多个独立的 Redis Master 节点(至少3个,通常5个)。客户端尝试在大多数(N/2 + 1)Redis 实例上获取锁,才能算成功。这提供了更高的可用性和容错性,但实现更复杂,性能开销也更大。
    • 读写锁 (ReadWriteLock): 允许多个读操作同时进行,但写操作是独占的。
    • 信号量 (Semaphore): 控制并发访问资源的数量。
    • 闭锁 (CountDownLatch): 类似 Java 的 CountDownLatch。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90509.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 导出word 实现饼状图导出--可编辑数据

📊 支持图表导出功能! 支持将 柱状图、折线图 图表以 Word 文档格式导出,并保留图例、坐标轴、颜色、数据标签等完整信息。 如需使用该功能,请私聊我,备注 “导出柱状图 / 折线图”。 生成的效果图如下:示例…

AI大模型平台

在科技浪潮迅猛推进的当下,AI大模型平台宛如一颗璀璨的新星,强势闯入大众视野,以其独特的魅力和强大的功能,深刻地变革着我们生活与工作的每一处角落。从日常智能助手的贴心陪伴,到专业内容创作的灵感激发;…

C# Console App生成的 dll文件

在使用 dotnet 8.0 创建一个 C# console app后,执行完编译操作,会发现除了生成可执行文件外,还生成一个 dll文件。 $ls ConsoleApp1 ConsoleApp1.dll ConsoleApp1.runtimeconfig.json ConsoleApp1.deps.json ConsoleApp1.pdb $ …

【AI】环境——深度学习cuda+pytorch配置

文章目录关键组件及关系显卡驱动GPU DriverCUDACUDA ToolkitcuDNNPytorch各组件版本选择驱动程序CUDA查看驱动及CUDA的最大支持版本CUDA Toolkit选自定义安装检验无法识别nvcccuDNNcondapip换源conda管理py包conda 换源查看列表、创建、克隆、激活、删除conda包管理包安装原则设…

观众信息设置与统计(视频高级分析与统计功能)

Web播放器(POLYV-html5-player)支持设置观众信息参数,设置后在播放器上报的观看日志中会附带观众信息,这样用户就可以通过管理后台的统计页面或服务端API来查看特定观众的视频观看情况了。 一、观众信息设置 播放器设置观众信息参…

《数据库》 MySQL库表操作

1. SQL语句基础 1.2 SQL简介 SQL:结构化查询语言(Structured Query Language),在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句,程序员和数据库管理员可以完成如下的任务 改变数据库的结构 更改系统的安全设置…

DSP的基础平台搭建

1、CCS6.0的安装安装步骤这里就不说了,只谈论最可能遇到的问题:可以看到为需要关闭防火墙和扫描;在这里将其都关闭,然后可以断掉网络,关闭联想管家,可能还是会出现防火墙提示,但是可以安装&…

下一代防火墙-终端安全防护

实验设备1、 山石网科(hillstone)系列下一代防火墙(实训平台v1.0中hillstone设备)2、 三层交换机一台(实训平台v1.0中cisco vios l2设备)3、 二层交换机一台(实训平台v1.0中cisco iol switch设备…

Scala实现网页数据采集示例

Scala 可以轻松实现简单的数据采集任务,结合 Akka HTTP(高效HTTP客户端)和 Jsoup(HTML解析库)是常见方案。Scala因为受众比较少,而且随着这两年python的热门语言,更让Scala不为人知,…

【IO复用】五种IO模型

文章目录五种IO模型Linux设计哲学BIONIOAIOSIOIO多路复用五种IO模型 Linux设计哲学 在linux系统中,实际上所有的I/O设备都被抽象为了文件这个概念,一切皆文件,磁盘、网络数据、终端,甚至进程间通信工具管道pipe等都被当做文件对…

FeatherScan v4.0 – 适用于Linux的全自动内网信息收集工具

前言 在平时渗透打靶的时候,经常要自己手工输入命令,做各种基本的信息收集,非常的繁琐,所以自研了一款工具,这款工具没有接入AI,因为不合适,接入了AI的话在一些不能上网的环境下进行信息收集&a…

如何精准筛选优质SEO服务资源?

核心要点: 中小企业选择SEO服务常陷困惑——效果难量化、承诺不透明、策略模糊化。本文剖析核心痛点,拆解技术合规性、策略透明度、行业经验匹配度等关键筛选维度,提供一套清晰的评估路径,助您在复杂市场中找到真正专业的合作伙伴…

在教育领域中,如何通过用户ID跑马灯来对视频进行加密?

文章目录前言一、什么是用户跑马灯二、用代码如何实现用户ID跑马灯的功能三、如何通过用户ID跑马灯来对视频进行加密?总结前言 在教育领域,优质视频课程易遭非法传播。为强化版权保护与责任追溯,引入基于用户ID的跑马灯水印技术成为有效手段…

MCP协议:AI时代的“万能插座”如何重构IT生态与未来

MCP协议:AI时代的“万能插座”如何重构IT生态与未来 在人工智能技术爆炸式发展的浪潮中,一个名为Model Context Protocol(MCP) 的技术协议正以惊人的速度重塑IT行业的底层逻辑。2024年11月由Anthropic首次发布,MCP在短…

同步,异步复位问题

1.同步复位的基本原理是,复位信号仅在时钟的有效边沿影响或重置触发器的状态。复位的主要目标之一是使 ASIC 在仿真时进入已知状态。由于复位树的扇出较大,复位信号相对于时钟周期可能成为 “晚到信号”。即使复位信号会通过复位缓冲树进行缓冲&#xff…

数组和指针回顾,练习与解析

代码见:登录 - Gitee.com 1.数组和指针练习与解析 1.1数组名 1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。 2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。 3.除此之…

【牛客刷题】活动安排

文章目录一、题目介绍二、解题思路2.1 核心问题2.2 贪心策略2.3 正确性证明三、算法分析3.1 为什么按结束时间排序?3.2 复杂度分析3.3 算法流程图解3.3.1 流程图说明3.3.2 关键步骤说明四、模拟演练五、完整代码一、题目介绍 活动安排 题目描述 给定 nnn 个活动&am…

第1讲:C语言常见概念

目录 一、什么是C语言? 二、C语言的历史与成就 三、编译器选择(VS2022) 1、编译与链接 2、编译器对比 3、VS2022的优缺点 四、VS项目与源文件、头文件介绍 五、第一个C语言程序 六、main函数 七、printf和库函数 八、关键字介绍 …

WinUI3入门18:从APP打开商店链接以及实现内购

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…

BI布局拖拽 (1) 深入react-gird-layout源码

因为有个拖拉拽的需求,类似于quickBi那样的效果。在网上调研了一下发现react-grid-layout实现效果类似,但其也有局限性,比如不支持嵌套,不支持在多个gridLyaout之间互相拖拽。 要求:基于react-grid-layout的思路&#…