Redis学习[7] ——如何使用Redis实现分布式锁?

news2025/1/21 0:57:42

如何用Redis实现分布式锁?

9.5.1 为什么Redis能用来实现分布式锁?

分布式锁是用于分布式环境下并发控制的一种机制,用于控制某个资源在同一时刻只能被一个应用所使用。如下图所示:

Redis可以被多个客户端共享访问,可以用来保存分布式锁,且Redis的读写性能高,可以应对高并发的锁操作常见。

9.5.2 如何实现分布式锁?

Redis 的 SET 命令有个 NX 参数可以实现「key不存在才插入」,所以可以用它来实现分布式锁:

  • 如果 key 不存在,则显示插入成功,可以用来表示加锁成功;
  • 如果 key 存在,则会显示插入失败,可以用来表示加锁失败。

基于 Redis 节点实现分布式锁时,对于加锁操作,我们需要满足三个条件:

  • 加锁包括了读取锁变量、检查锁变量值和设置锁变量值三个操作,但需要以原子操作的方式完成,所以,我们**使用 SET 命令带上 NX 选项**来实现加锁;

  • 锁变量需要设置过期时间,以免客户端拿到锁后发生异常,导致锁一直无法释放,所以,我们在 SET 命令执行时加上 EX/PX 选项,设置其过期时间

  • 锁变量的值需要能区分来自不同客户端的加锁操作,以免在释放锁时,出现误释放操作,所以,我们使用 SET 命令设置锁变量值时,每个客户端设置的值是一个唯一值,用于标识客户端

    SET lock_key unique_value NX PX 10000
    
    # lock_key 就是 key 键;
    # unique_value 是客户端生成的唯一的标识,区分来自不同客户端的锁操作;
    # NX 代表只在 lock_key 不存在时,才对 lock_key 进行设置操作;
    # PX 10000 表示设置 lock_key 的过期时间为 10s,这是为了避免客户端发生异常而无法释放锁。
    

解锁的过程就是将 lock_key 键删除,但不能乱删,要保证执行操作的客户端就是加锁的客户端,即先判断先判断锁的 unique_value 是否为加锁客户端。因此,解锁是两个步骤,无法保证原子性。因此Redis需要引入Lua脚本来实现原子操作,解锁的Lua脚本如下:

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

用户通常需要编写适当的 Lua 脚本并通过 Redis 客户端发送到 Redis 服务器执行。这是因为分布式锁的解除需要原子操作,而 Lua 脚本可以保证在 Redis 中的操作是原子的。发送到Redis服务器方法如下:

## 后面的1是指有一个键
> EVAL "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock_key unique_value

不过,为了简化这一过程,一些 Redis 客户端库已经内置了处理分布式锁的功能。这些库通常会封装 Lua 脚本的编写和执行过程,使用户可以更方便地使用分布式锁

9.5.3 基于Redis的分布式锁的优缺点?

优点

  • 性能高效;
  • 实现方便;
  • 避免单点故障;

缺点

  • 超时时间不好设置;
  • Redis 主从复制模式中的数据是异步复制的,这样**导致分布式锁的不可靠性**。
9.5.4 Redis如何解决集群情况下分布式锁的可靠性?

Redlock 算法的基本思路,是让客户端和多个独立的 Redis 节点依次请求申请加锁,如果客户端能够和半数以上的节点成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁,否则加锁失败

可以看到,加锁成功要同时满足两个条件:

  • 条件一:客户端从超过半数(大于等于 N/2+1)的 Redis 节点上成功获取到了锁;
  • 条件二:客户端从大多数节点获取锁的总耗时(t2-t1)小于锁设置的过期时间。

资料参考

内容大多参考自:图解Redis介绍 | 小林coding (xiaolincoding.com)

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

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

相关文章

jenkins自动化构建docker镜像并上传至harbor仓库

1、插件下载 首先进入jenkins之后需要现在“Maven”、“GitLab”、“Jdk”、“SSH”、“Git”的相关插件,这里不再赘述,需要什么插件直接安装即可 搜索对应插件后选择直接安装即可 2、系统全局配置 2.1 Maven配置 配置maven安装的相应的setting文件 …

How does age change how you learn?(2)年龄如何影响学习能力?(二)

Do different people experience decline differently? 不同人经历的认知衰退会有不同吗? Do all people experience cognitive decline uniformly?Or do some people’s minds slip while others stay sharp much longer? 所有人经历的认知衰退都是一样的吗?还是有些人…

计时器(Python)

代码 import time from tkinter import ttk import threading from tkinter import scrolledtext import tkinter as tkclass TimerApp:def __init__(self, root):self.root rootself.root.title("计时器")self.screen_w, self.screen_h self.root.winfo_screenwi…

Conditional Detr

encoder和detr相同,只修改了decoder部分。

(STM32笔记)九、RCC时钟树与时钟 第一部分

我用的是正点的STM32F103来进行学习,板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。 九、RCC时钟树与时钟 九、RCC时钟树与时钟1、时钟树HSE时钟HSI时钟锁相环时钟系统时钟HCLK时钟PCLK1时钟PCLK2时钟RTC时钟独…

iPhone苹果手机Safari浏览器怎么收藏网页?

iPhone苹果手机Safari浏览器怎么收藏网页? 1、iPhone苹果手机上找到并打开Safari浏览器,并访问要收藏的网页; 2、打开网页后,点击导航上的更多功能; 3、在更多里,找到并点击添加到个人收藏,完成储存即可添…

2023华为od机试C卷【分配土地】Python实现

思路: 我们可以用哈希结构,此题适合用字典,键为出现的非零数字,值为列表,列表为【minrow,maxrow,minrol,maxrol] import sys def main():m,n map(int,input().split())rects {}for i in range(m):nums [int(i) f…

EFK之filebeat用法进阶

接上一章节:https://blog.csdn.net/weixin_46546303/article/details/140279197?spm1001.2014.3001.5501 一、filebeat module 输入流 1.filebeat module作用 Filebeat 模块的主要作用是简化日志数据的收集和处理过程。通过使用模块,你可以快速地配置…

java计算机毕设课设—网上招聘系统(附源码、文章、相关截图、部署视频)

这是什么系统? java计算机毕设课设—网上招聘系统(附源码、文章、相关截图、部署视频) 网上招聘系统的设计与实现旨在提供一个便捷、高效的在线平台,使个人求职者和公司能够有效地进行职位申请和人才招聘。该系统特别设计了两种…

Golang | Leetcode Golang题解之第318题最大单词长度乘积

题目&#xff1a; 题解&#xff1a; func maxProduct(words []string) (ans int) {masks : map[int]int{}for _, word : range words {mask : 0for _, ch : range word {mask | 1 << (ch - a)}if len(word) > masks[mask] {masks[mask] len(word)}}for x, lenX : ra…

狮子鱼 CMS ApiController.class.php SQL 注入漏洞

本章提供的所有内容仅供学习、交流和分享用途&#xff0c;只供参考。本站资源禁止并谢绝未经本站许可的使用&#xff0c;如若欲转载&#xff0c;请署名以及注明出处&#xff0c;请务必以文字链接的形式标明或保留文章原始出处和作者的信息。本站(原创)文章、资源、图片等所有内…

嵌入式全栈开发学习笔记---数据结构(顺序表)

目录 顺序结构 顺序表初始化 顺序表插入 顺序表遍历操作 顺序表前驱和后继 顺序表查找操作 顺序表删除操作 顺序表清空销毁 顺序表销毁操作 完整代码 List.c List.h Main.c 顺序表优缺点&#xff08;面试可能会考&#xff09; 上一节我们介绍了数据结构的一般概念…

【ModelSim】仿真问题记录

1、波形出不全&#xff1a; 1、甚至连clk波形都出不来 2、个别波形只有到仿真结束的时候才出现 解决办法&#xff1a; 1、添加波形需要是实例中的net 2、排查是否存在声明与示例的位宽不一致的信号 3、观察是否存在未初始化的变量寄存器 4、缩短整个仿真的步长 2、Instance列…

【HBZ分享】spring启动时自动装配的位置

自动装配流程 springboot启动时&#xff0c;自动装配逻辑在SpringBootApplication这个符合注解中的EnableAutoConfiguration新版springboot3会扫描META-INF的spring文件夹下的org.springframework.boot,autoconfigure,AutoConfiguration.imports文件&#xff0c;会把这里所有写…

FSMC--灵活的静态存储控制器

&#xff08;1&#xff09;在STM32F1系列&#xff08;及F407&#xff09;的芯片上封装了FSMC外设&#xff0c;支持拓展SARM作为RAM。 &#xff08;2&#xff09;SRAM和SDRAM的区别&#xff1a; 存储结构&#xff1a;SRAM使用锁存器、SDRAM使用电容通讯方式&#xff1a;SRAM多…

Leaf分布式ID

文章目录 系统对Id号的要求UUIDsnowflakeLeafLeaf-snowflakeLeaf-segmentMySQL自增主键segment双buffer 系统对Id号的要求 1、业务 1&#xff09;全局唯一性&#xff1a;不能出现重复的ID号&#xff0c;既然是唯一标识&#xff0c;这是最基本的要求 2&#xff09;趋势递增&a…

使用LLM(Large Language Model)进行主题建模

随着互联网技术的快速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域取得了显著的进步。其中&#xff0c;大型语言模型&#xff08;LLM&#xff09;在文本生成任务中表现尤为抢眼。本文旨在探讨LLM在主题建模方面的优势&#xff0c;以及如何将其应用于文本生成任…

深度图进行运算检测物体表面粗糙度

文章目录 应用场景算法原理核心代码应用场景 不同程度凹凸的零件表面粗糙度对零件的磨损产生影响,很大程度上关系到产品性能和使用寿命。不同于单独使用的产品,零件需要在装配中与其他零件相连,密封性和磨损量是厂商需要考虑的一大加工要素;其次,产品外观和触感也会影响到…

数据结构链表2(常考习题1)(C语言)

移除链表元素&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 解题思路&#xff1a; 情况1&#xff1a; 情…

【vluhub】skywalking

SkyWalking是一个开源监控平台&#xff0c;用于从服务和云原生基础设施收集、分析、聚合和可视化数据 低版本存在sql注入漏洞 访问地址 http://192.168.203.12:8080/graphql burpsuite抓数据包 替换 {"query":"query queryLogs($condition: LogQueryConditi…