Redis原理篇——分布式锁

news2025/2/28 12:39:38

Redis原理篇——分布式锁

    • 分布式锁是什么?
    • 分布式锁有哪些特性?
    • 分布式锁常用实现方式
    • Redis 实现分布式锁
      • 一、简单的 Redis 锁
      • 二、带过期时间的 Redis 锁
      • 三、加上 Owner 的 Redis 锁
      • 四、Lua 脚本确保原子性

分布式锁是什么?

分布式锁是在分布式系统中用来确保当多个进程或服务在不同的计算机上同时尝试访问和操作同一份资源时,能够协调一致地进行,避免数据冲突和不一致性的问题。

分布式锁就像是一个网络版的门卫,确保在多台计算机上运行的程序不会同时操作同一个数据。想象一下,每台计算机都要先拿到这个门卫的钥匙,才能操作数据。这样,就能防止数据混乱,确保每次只有一个程序在使用数据。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

分布式锁有哪些特性?

  • 互斥性:很好理解,确保在任何时刻,只有一个客户端可以持有锁。这意味着当一个进程或线程成功获取到锁时,其他任何尝试获取该锁的进程或线程都会被阻止,直到锁被释放。

老王进去了老李就不能再进了!!

  • 锁失效机制:为了 防止死锁,分布式锁应该具有 超时机制 。如果持有锁的进程因崩溃或其他原因未能释放锁,锁将在设定的超时时间后自动释放。

老王在里面干太久了,这不行,挂了都不知道,甭管你挂没挂,不出来拉倒,别人还要进去呐!

  • 对称性:加锁的必须和解锁的是 同一个竞争者 ,不能把其他的竞争者持有的锁给释放掉了

跟大爷打招呼,拿着钥匙进去的,得和出来的时候还钥匙的是一个人,不能老王进去老李出来吧,那不见鬼了!!

  • 高可用:需要能有一定程度的 异常处理能力 容灾能力 ,确保业务不会出现中断

保安大爷不行了,干不动了,换那个新来的大学生顶上啊!!

分布式锁常用实现方式

  • 基于缓存(如 Redis):使用缓存系统的原子操作来实现锁。例如,Redis的SETNX命令可以用来设置一个不存在的键,如果键已存在,则操作失败,这可以用来实现锁的互斥性。
  • 基于数据库:利用数据库的唯一性约束来实现锁机制。通过向数据库表中插入具有唯一索引的记录来获取锁,操作完成后删除记录来释放锁。
  • 基于Zookeeper:Zookeeper提供了一种基于临时节点和顺序节点的锁实现机制。客户端可以创建一个临时顺序节点,并检查是否为最小节点来获取锁,释放锁时删除该节点。

而本篇文章,将基于 Redis 缓存详细探讨分布式锁的使用

Redis 实现分布式锁

一、简单的 Redis 锁

想象一下,我们的系统是一个超级忙碌的酒吧,而分布式锁就是酒吧里唯一的洗手间的钥匙。客户(也就是进程)想要使用洗手间(也就是资源),他们需要先拿到钥匙。

SET restroom_key "occupied" NX

这条命令就像是在问酒保:“嘿,洗手间钥匙在吗?”如果NX(Not eXists)标志起作用,那就意味着洗手间空着,你就可以拿到钥匙(也就是锁)。如果钥匙“不存在”,那就意味着洗手间已经有人在用了,你得等等。最后,在使用完成之后会归还钥匙(delete)

不足之处

但是,如果老王进了洗手间,然后突然不见了(也就是进程崩溃了)或者没卫生纸了需要其他人递过来但又没手机(发生死锁),怎么办?我们的钥匙就永远被锁在里面了。这就引出了我们的第二部分。

二、带过期时间的 Redis 锁

为了防止洗手间被永久占用,我们给钥匙加上了一个计时器。

SET restroom_key "occupied" NX EX 5

现在,不管老王发生了什么,5分钟后钥匙也会自动回到酒保手里,其他客户就可以使用洗手间了。

进一步的不足

但是,如果老王今天身体确实不舒服,窜了太长的时间了,或者因为其他原因接个电话什么( 比如说网络延迟或者 GC卡顿等原因)导致他没消失但一直占着茅坑不拉屎,然后钥匙回到了酒保手上,另一个人老张就拿着钥匙进去了

然后关键来了,这时候老王结束了,然后出来的时候按照流程就把钥匙(也就是锁),但是实际上他还的是老张的钥匙,而这时候老张不就完犊子了,你老王的问题别把我也扯进去!!

三、加上 Owner 的 Redis 锁

分布式锁应该满足, 谁申请谁释放 的原则,不能释放别人的锁

因此我们决定在钥匙(锁)上刻上名字,这样只有名字匹配的人(一般是进程的 uuid )才能归还钥匙。

SET restroom_key “老张” NX EX 5

如果老张有了钥匙,那么只有老张能归还它。如果老王试图归还一个写着“老张”的钥匙,酒保会说:“不行,这不是你的钥匙。”

再进一步的问题

可以看到,解锁是有两个操作,先查看是否是自己的钥匙,是的话再归还钥匙(delete)

但整个解锁操作并不是原子性的,可能检查的时候是自己的,而归还删除的时候已经是别人的了( 比如说你刚获取到是自己的锁,然后处于了一个很长的 GC…)

四、Lua 脚本确保原子性

这时就需要 Lua 脚本来保证解锁的原子性,因为 Redis 在执行 Lua 脚本时,可以以原子性的方式执行,保证了锁释放操作的原子性。

// 释放锁时,先比较 unique_value 是否相等,避免锁的误释放
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

这样就通过使用 SET 命令 加上 NXEX 参数 以及 Owner 标志 和 Lua 脚本在 Redis 单节点上完成了分布式锁的加锁和解锁。

通过以上方式,分布式锁的前三个特性 互斥性 、 锁失效机制以及对称性就基本解决了,最后还有一个高可用性就放到下节讲咯 ~~

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

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

相关文章

HTML解析之Beautiful Soup

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Beautiful Soup是一个用于从HTML和XML文件中提取数据的Python库。Beautiful Soup 提供一些简单的、函数用来处理导航、搜索、修改分析树等功能。Beau…

YOLOX: 无锚点机制 + 解耦头部设计 + 动态标签分配策略的高性能目标检测器 + Apache-2.0 开源可商用

YOLOX: 无锚点机制 解耦头部设计 动态标签分配策略的高性能目标检测器 Apache-2.0 开源可商用 1. Decoupled Head 解耦头部的使用2. 强化数据增强策略3. 采用无锚点检测机制4. 多正样本策略5. SimOTA标签分配策略6. CSPDarkNet 网络结构DarkNet53 的深度特征提取能力DarkNet…

简单http客户端程序

要求和目的 深入理解http协议以及http下载相关功能的程序设计 实验环境 Java语言,PC平台 实验要求 基本要求:使用Socket类,实现一个简单的HTTP客户端程序。用户输入URL,该程序可以从服务器下载URL指定的资源,并将之…

LabVIEW RT在非NI硬件上的应用与分析

LabVIEW RT(实时操作系统)可运行在非NI(National Instruments)硬件上,如研华工控机,但需要满足特定硬件要求。本文从硬件要求、开发和运行差异、可靠性、稳定性、优势和成本等多角度详细分析在非NI硬件上运…

后端返回前端时间格式化

时间格式化的方法总共包含以下 5 种。 1.前端时间格式化 JS 版时间格式化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function dateFormat(fmt, date) { let ret; const opt { "Y": date.getFullYear().toString(), // 年 …

挂耳式耳机哪个牌子好性价比高、五大招牌力作精选归纳

如果说你很喜欢户外运动,日常生活中也是需要经常佩戴耳机,那么你一定有了解到耳机是开放式耳机,这类耳机无论在户外运动防水防汗还是在耳朵健康方面都具备它的优点,在市面上是很受欢迎的。 但面对市面上不同品牌的耳机都会显得眼…

【面试干货】深入理解Java中的final关键字

【面试干货】深入理解Java中的final关键字 一、被 final 修饰的类二、被 final 修饰的方法三、被 final 修饰的变量四、被 final 修饰的常量 💖The Begin💖点点关注,收藏不迷路💖 在Java中,final关键字有多种用途&…

组合和外观模式

文章目录 组合模式1.引出组合模式1.院系展示需求2.组合模式基本介绍3.组合模式原理类图4.解决的问题 2.组合模式解决院系展示1.类图2.代码实现1.AbsOrganizationComponent.java 总体抽象类用于存储信息和定义方法2.University.java 第一层,University 可以管理 Coll…

atcoder ABC 355-C题详解

atcoder ABC 355-C题详解 ​ Problem Statement There is an NN grid, where the cell at the i-th row from the top and the j-th column from the left contains the integer N(i−1)j. Over T turns, integers will be announced. On Turn i, the integer Ai​ is anno…

C++入门8 构造函数析构函数顺序|拷贝构造

一&#xff0c;构造函数析构函数 调用顺序 我们先来看下面的代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> using namespace std; class student { public:char my_name[20];int my_id;student(int a) {my_id a;co…

使用超声波麦克风阵列预测数控机床刀具磨损

预测性维护是使用传感器数据来推断机器状态&#xff0c;并从这些传感器数据中检测出在故障发生之前存在的缺陷或故障的过程。预测性维护在所有工业领域都是一种日益增长的趋势&#xff0c;包括轴承故障检测、齿轮磨损检测或往复式机器中的活塞磨损等许多其他例子。在预测性维护…

ADS基础教程20 - 电磁仿真(EM)参数化

EM介绍 一、引言二、参数化设置1.参数定义2.参数赋值3.创建EM模型和符号 四、总结 一、引言 参数化EM仿真&#xff0c;是在Layout环境下创建参数&#xff0c;相当于在原理图中声明变量。 二、参数化设置 1.参数定义 1&#xff09;在Layout视图&#xff0c;菜单栏中选中EM&g…

哈喽GPT-4o——对GPT-4o 写论文的思考与看法

目录 几小时即可完成一份1万字论文的编写1、改写降重2、同义词替换降重3、避免连续相同4、缩写扩写降重5、关键词汇替换降重6、句式变换降重7、逻辑重组8、综合改写9、数据呈现方式变更10、概念解释降重 大家好&#xff0c;我是哪吒。 在ChatGPT4o对话框中输入&#xff1a;写一…

继承-进阶-易错点

子类同名方法隐藏父类方法 即使调用不匹配也不会再去父类寻找&#xff0c;而是直接报错 //下面代码输出结果&#xff1a;( )&#xfeff;class A { public:void f(){ cout<<"A::f()"<<endl; }int a; };class B : public A { public:void f(int a){c…

若依微服务Docker部署验证码出不来怎么办?

最近,有许多人反馈在使用 Docker 部署若依微服务项目时,遇到验证码无法显示的问题。本文将重点介绍解决该问题的注意事项以及整个项目的部署流程。之前我们也撰写过微服务部署教程,本文将在此基础上进行优化和补充。你也可以参考我之前写的部署教程:https://yang-roc.blog.…

做材料科学领域研究热点:高通量多尺度材料计算和机器学习

研究背景 材料科学是一个重要领域&#xff0c;涉及物质的研究和利用。随着科技进步&#xff0c;材料学已成为多学科交叉的前沿领域之一&#xff0c;融合物理、化学、数学、信息、力学和计算科学等知识。寻找更坚固的新材料已成为当今急需解决的问题。 材料基因工程作为一项颠覆…

万相台的功能是什么?如何使用万相台?

1.特点&#xff1a; 万相台是一个智能渠道&#xff0c;可控性弱&#xff0c;高转化&#xff0c;人群&关键词是黑盒&#xff1b; 2.场景多&#xff1a; 有拉新快、活动加速、上新快、货品加速、活动加速、多目标直投、全站推等&#xff1b; 3.扣费逻辑&#xff1a;cpc付…

Elasticsearch:简化数据流的数据生命周期管理

作者&#xff1a;来自 Elastic Andrei Dan 今天&#xff0c;我们将探索 Elasticsearch 针对数据流的新数据管理系统&#xff1a;数据流生命周期&#xff0c;从版本 8.14 开始提供。凭借其简单而强大的执行模型&#xff0c;数据流生命周期可让n 你专注于数据生命周期的业务相关方…

动态规划-简单多状态dp问题 -- 按摩师

动态规划-简单多状态dp问题 – 按摩师 文章目录 动态规划-简单多状态dp问题 -- 按摩师题目重现算法流程示例代码 题目重现 题目链接&#xff1a;按摩师 - 力扣 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在每次预约服务之间要有休息时…

Linux网络编程:多路转接|select|poll

目录 前言&#xff1a; 1.IO多路转接---select 1.1.接口认识 1.2.select如何进行多路转接 1.3.select多路转接的优缺点 2.IO多路转接---poll 2.1.接口认识 2.2.poll如何进行多路转接 2.3.poll多路转接优缺点 前言&#xff1a; 多路转接&#xff08;也称为IO多路复用&a…