如何用Redis实现分布式锁?


theme: smartblue

分布式锁是什么?为什么要有这个技术,解决了什么问题?

讲到分布式锁,我们会很容易联想到单机锁。在java多线程编程中,通常我们会使用锁来保护共享变量,来保证线程安全。这里面的锁作用范围是同一个进程中。如果是多个进程,应该怎么保护共享资源?这就是分布式锁来解决的问题。分布式解决的是在多个进程,如果确保对共享资源操作的正确性。
那我们应该如何实现分布式锁?
需要借助其他第三方服务来解决,比如mysql、zookeeper、Redis等。

不同实现方案

mysql

利用数据库的唯一约束特性来实现锁的互斥性。比如创建一张锁表,表中包含锁名称(用于区分不同的业务锁)、锁定状态等字段。当某个服务要获取锁时,向表中插入一条对应锁名称的记录,如果插入成功则表示获取到锁,若插入失败(违反唯一约束)则说明锁已被其他服务占有。释放锁时,只需删除对应的记录即可。

  • 优点
    实现相对简单,理解容易,借助数据库的稳定性和持久性保证锁的可靠性,适用于并发量不是特别巨大的场景。
  • 缺点
    性能相对较差,获取锁和释放锁涉及数据库操作,有一定的 I/O 开销;存在单点故障问题,如果数据库出现故障,整个分布式锁机制将受到影响;可能会出现死锁情况,比如获取锁的服务崩溃,没来得及释放锁。

基于 Zookeeper 实现分布式锁

Zookeeper 是一个分布式协调服务,它通过节点的创建和删除以及节点的顺序性等特性来实现分布式锁。通常利用临时顺序节点来实现,当一个服务要获取锁时,在 Zookeeper 指定路径下创建一个临时顺序节点,然后获取该路径下所有子节点,判断自己创建的节点是否是序号最小的节点,如果是则表示获取到锁;如果不是,则监听序号比自己小的节点的删除事件,当监听的节点被删除时,再次判断自己是否为最小节点来获取锁。释放锁就是删除对应的临时顺序节点。在 Java 中可以通过 Curator 等框架来方便地操作 Zookeeper 实现分布式锁。

  • 优点
    可靠性高,基于 Zookeeper 的分布式一致性协议(如 ZAB 协议),能保证在集群环境下锁的一致性;具备高可用和容错性,Zookeeper 集群可以应对节点故障等情况;可以实现阻塞式获取锁,方便处理需要等待锁释放的业务场景。
  • 缺点
    性能相比 Redis 稍差一些,因为涉及到节点的创建、查询、监听等一系列操作,有一定的网络开销和 Zookeeper 服务器的处理成本;实现相对复杂,需要对 Zookeeper 的相关概念和操作比较熟悉,代码的编写和理解成本相对较高。

Redis分布式锁方案

一款优秀分布式锁应该具有什么特点?

互斥性

含义:在任意时刻,对于同一个被保护的资源,只能有一个客户端能够获取到分布式锁,其他客户端若尝试获取,需等待当前持有锁的客户端释放锁之后才有机会获取。这确保了在分布式环境下针对共享资源的并发访问能够按照顺序依次进行,避免多个客户端同时操作资源而导致数据不一致等问题。

可重入性

一个已经获取到分布式锁的客户端,在锁未释放期间,如果再次请求获取该锁,仍然能够成功获取,并且锁的释放次数需要和获取次数严格匹配才能最终真正释放锁。这在一些具有递归调用或者嵌套调用逻辑的业务场景中非常重要,避免自己把自己 “锁死” 而无法继续后续操作。类似java多线程中的可冲入锁概念

阻塞特性与超时机制

  • 阻塞特性
  • 含义:当客户端尝试获取锁但当前锁已被其他客户端持有时,该客户端能够阻塞等待,直到获取到锁或者超时为止,而不是立刻返回失败结果。这样可以保证在高并发情况下,客户端有机会获取到锁去操作资源,不用频繁地发起获取锁的请求去轮询。

  • 超时机制

  • 含义:为了防止某个客户端获取锁后由于异常情况(比如进程崩溃、网络故障等)一直没有释放锁,导致其他客户端无限期等待,需要给锁设置一个超时时间,一旦超过这个时间,锁会自动释放,让其他客户端有机会获取锁。

具体实现:

单机版本的分布式锁

最简单的分布式锁: setnx 这个命令代表如果key不存在,然后才设置。操作完成后del删除这个key就行。
但是有一个很大的问题,客户端1拿到锁之后,如果没有释放锁,或者进程挂了,没机会释放锁。其他客户端就永远没有机会拿到锁。
如何解决?
很自然的一个思路,给这个锁设置一个有效时间,类似锁设置一个超时时间,过了这个时间,自动释放锁,给其他客户端一个机会获取临界资源。我们可以使用redis 提供的 SET key 1 EX 10 NX 该命令是原子性的。
看起来很完美了,但是我们再细想一下。首先就是这个过期时间,现实中很难设置准确,设置太长,导致资源浪费,设置太短,又没法确保客户端执行完业务代码。我们有没有一种机制能够自动给锁延长时间呢?答案是存在的,我们开启一个守护线程(我们通常称为看门狗线程),定时检测这个锁的失效时间,如果锁快要过期了,操作共享资源还没有完成,我们就可以自动给锁进行续期,重新设置过期时间。
这个时候我们再想一下,还存在什么问题? 客户端释放锁,会无脑释放,并不会检查是不是自己的锁,我们需要在客户端加锁的时候,设置一个唯一标识,比如UUID,线程id等。释放锁的时候,先判断一下是不是自己的锁,是自己的锁,才会进行释放。这个时候,会设计到redis不同命令。redis通过lua脚本来确保原子性。
大概流程是:
加锁。 设置锁,并且设置一个唯一标识来标识这个锁, 操作共享资源,释放锁,lua脚本,先判断是不是自己的锁,然后再del锁。

分布式场景下的锁

如果有多台redis实例,如何实现呢?
1、客户端先获取当前时间戳t1。
2、客户端依次向n个redis实例发起加锁命令,并且每一个请求设置超时时间(这个时间要远小于锁的有效时间,不然你还没设置,锁就到期了,没有意义),如果某个实例加锁失败,就立即向下一个实例申请加锁。
3、如果超过一般以上的redis实例加锁成功,就再次获取当前时间戳t2。t2-t1看一下是否超过了锁的超时时间,没有代表客户端加锁成功,否则失败。
4、加锁成功就可以操作共享资源。
5、如果加锁失败,就需要向全部节点释放锁的请求。

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

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

相关文章

免费GIS工具箱:轻松将glb文件转换成3DTiles文件

在GIS地理信息系统领域,GLB文件作为GLTF文件的二进制版本,主要用于3D模型数据的存储和展示。然而,GLB文件的使用频率相对较低,这是因为GIS系统主要处理的是地理空间数据,如地图、地形、地貌、植被、水系等,…

音视频入门基础:MPEG2-TS专题(21)——FFmpeg源码中,获取TS流的视频信息的实现

一、引言 通过FFmpeg命令可以获取到TS文件/TS流的视频压缩编码格式、色彩格式(像素格式)、分辨率、帧率信息: ./ffmpeg -i XXX.ts 本文以H.264为例讲述FFmpeg到底是从哪个地方获取到这些视频信息的。 二、视频压缩编码格式 FFmpeg获取TS文…

BenchmarkSQL使用教程

1. TPC-C介绍 Transaction Processing Performance Council (TPC) 事务处理性能委员会,是一家非盈利IT组织,他们的目的是定义数据库基准并且向产业界推广可验证的数据库性能测试。而TPC-C最后一个C代表的是压测模型的版本,在这之前还有TPC-A、…

火山引擎发布数据飞轮 2.0,AI 重塑企业数据消费

12 月 18 日,在 2024 冬季火山引擎 FORCE 原动力大会上,火山引擎数智平台(VeDI)正式升级发布数据飞轮 2.0 模式。 延续去年 4 月发布的数据飞轮“以数据消费促资产建设,以数据消费助业务发展”的核心内涵,…

LLaMA-Factory 单卡3080*2 deepspeed zero3 微调Qwen2.5-7B-Instruct

环境安装 git clone https://gitcode.com/gh_mirrors/ll/LLaMA-Factory.git 下载模型 pip install modelscope modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /root/autodl-tmp/models/Qwen/Qwen2.5-7B-Instruct 微调 llamafactory-cli train \--st…

合并比对学习资料

目录 ContractComparison已开源: ContractComparison已开源: GitHub - UnstoppableCurry/ContractComparison: Comparison of General Chinese Contracts with OCR Pytorch

全速下载 50M/S,不限速下载就是香

近几年来虽说各大网盘层出不穷,各有乾坤,而这其中某些网盘对于网速限制非常严重,这也是很多小伙伴一直吐槽的点,并且某些网盘下载文件还需要安装客户端,并且每家的限速方式不同,有的限速取决于文件大小&…

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效…

RunCam WiFiLink连接手机图传测试

RunCam WiFiLink中文手册从这里下载 一、摄像头端 1.连接天线(易忘) 2.打开摄像头前面的盖子(易忘) 3.接上直流电源,红线为正,黑线为负 4.直流电源设置电压为14v,电流为3.15A, 通…

AI的进阶之路:从机器学习到深度学习的演变(二)

AI的进阶之路:从机器学习到深度学习的演变(一) 三、机器学习(ML):AI的核心驱动力 3.1 机器学习的核心原理 机器学习(Machine Learning, ML)突破了传统编程的局限,它不再…

WordPress 去除?v= 动态后缀

Wordpress url后面带有?vxxx的参数符,这种现象出现在安装了Woocommerce插件的店铺类型站点上,参数的作用是帮助系统根据用户的geographic定位计算 tax and shipping fee。 如何删除? 后台进入WooCommerce Settings ,将根据IP定…

Spring Cloud Gateway 源码

Spring Cloud Gateway 架构图 按照以上架构图,请求的处理流程: 1.客户端请求发送到网关 DispatcherHandler 2.网关通过 HandlerMapping 找到相应的 WebHandler 3.WebHandler生成FilterChain过滤器链执行所有的过滤器 4.返回Response结果 自动装配类Gat…

数据结构漫游记:初识vector

​ 嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的…

go-zero负载均衡实现原理

1. 什么是负载均衡 关于微服务分布式及集群的概念即定义,在业界中这些往往会同时在同一个项目中,而集群在微服务中主要为服务的运行保障高可用。 比如:在当前的项目情况下,我们可能针对用户服务部署两台服务以保障用户服务的高可用…

【Rust自学】4.4. 引用与借用

4.4.0 写在正文之前 这一节的内容其实就相当于C的智能指针移动语义在编译器层面做了一些约束。Rust中引用的写法通过编译器的约束写成了C中最理想、最规范的指针写法。所以学过C的人对这一章肯定会非常熟悉。 喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文…

Apache Solr RCE(CVE-2017-12629)--vulhub

Apache Solr 远程命令执行漏洞(CVE-2017-12629) Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个…

OpenGL ES 01 渲染一个四边形

项目架构 着色器封装 vertex #version 300 es // 接收顶点数据 layout (location 0) in vec3 aPos; // 位置变量的属性位置值为0 layout (location 1) in vec4 aColors; // 位置变量的属性位置值为1 out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main() {gl…

游戏渠道假量解决方案

某推广公司在推广过程中被查出“短期内点击量激增”“存在同一地址多次访问”“已注册用户重复注册”等数据作弊行为,法院判罚退还服务费200余万元,并赔偿违约金约350万元。 某公司为提升其游戏在应用商店榜单排名,委托某网络公司进行下载、注…

物联网:全面概述、架构、应用、仿真工具、挑战和未来方向

中文论文标题:物联网:全面概述、架构、应用、仿真工具、挑战和未来方向 英文论文标题:Internet of Things: a comprehensive overview, architectures, applications, simulation tools, challenges and future directions 作者信息&#x…

29、基于springboot的网上购物商城系统研发

本课题是根据用户的需要以及网络的优势建立的一个基于Spring Boot的网上购物商城系统,来满足用户网络购物的需求。 本网上购物商城系统应用Java技术,MYSQL数据库存储数据,基于Spring Boot框架开发。在网站的整个开发过程中,首先对…