Redis 典型应用——分布式锁

news2024/10/6 8:23:35

一、什么是分布式锁

在一个分布式的系统中,也会涉及到多个节点访问同一个公共资源的情况,此时就需要通过锁来做互斥控制,避免出现类似于 "线程安全" 的问题;

而 Java 中的 synchronized,只能在当前进程中生效,在分布式的这种多个进程多个主机的场景下就无能为力了,此时就要使用到分布式锁;

考虑网购秒杀这样一个场景,限量 1 件商品,现有两个用户(两个客户端),在第一个用户访问一个服务器查询商品剩余量 > 0 之后,执行 -= 1 之前,第二个用户访问另一个服务器,查询此时商品剩余量仍然 > 0,也会执行 -= 1 操作,此时就会存在超卖问题(一个东西同时卖给两个用户);

在这个过程中,为了防止穿插执行的情况,可以使用 MySQL 的事务来解决,但如果使用的数据库不是 MySQL,没有事务,或者执行一段特定的操作,就不能使用 MySQL 的事务了;

此时就要使用分布式锁来解决上述问题,所谓的分布式锁,也是一个 / 一组单独的服务器程序,给其他服务器提供加锁这样的服务;Redis 就是一种典型的可以用来实现分布式锁的方案(mysql,zookeeper 也可以实现分布式锁的效果);

在购买过程前,需要下加锁,完成购买操作之后,再解锁,这样在购买期间,就不会被其他服务器穿插执行了;

二、Redis 实现分布式锁

1. setnx

Redis 实现分布式锁依靠 setnx 命令, setnx key value,如果 key 存在,就设置失败,否则设置 key value;

通过 setnx 实现加锁后,服务器执行相应逻辑之后,解锁就要通过 del 命令来删除 key;

2. set nx ex

如果某个服务器加锁成功后,执行相应逻辑时,服务器宕机,没有执行到解锁操作,就会导致其他服务器也无法获取到这个没有释放的锁(没有删除的 key);

因此就要为该 key 设置过期时间,一旦过期时间到了,就会自动删除该 key,可以使用 Redis 中的set nx ex 命令;

那能否使用 setnx 命令 + expire 设置过期时间呢?

答案是不能的,因为 Redis 中的多个命令之间是不能保证原子性的,不保证执行成功,因此使用一条命令实现是更稳妥的;

3. 引入校验 Id

加锁就是设置一个 key value,而解锁就是把相应的 key 删除;

那就可能存在服务器 1 执行了加锁操作,而服务器 2 执行了解锁操作;(误操作,bug)

这就需要引入校验机制,为每个服务器编号,在设置 key value 的时候,key 对应要对哪个资源加锁,value 就可以存储服务器的编号(标识出当前锁是哪个服务器加上的);

在解锁的时候,先判断该锁对应的编号是否为当前服务器的编号,如果是,才进行解锁操作;

4. 引入 lua 脚本

在上述解锁的过程中,需要先判定,再进行删除,这是两步操作(不是原子的),一个服务器内部,也可能是多线程的,若此时,该服务器内部有两个线程都在执行上述操作,就可能出现问题

此时可以使用 Redis 的事务解决该问题(避免插队),但实践中往往使用 lua 脚本来解决该问题;

lua 是一个特别轻量的编程语言,Lua 语法简单精炼,执行速度快,解释器也比较轻量,并且 Redis 本身就支持 Lua 作为内嵌脚本;因此可以使用 lua 编写一些逻辑,把这个脚本上传到 Redis 服务器上来执行,执行 lua 脚本的过程中是原子的;Redis 官方文档中也明确说到,lua是事务的替代方案;

if redis.call('get',KEYS[1]) == ARGV[1] then 
 return redis.call('del',KEYS[1]) 
else 
 return 0 
end;

上述代码可以编写成一个 .lua 后缀的⽂件,由 redis-cli  或者  jedis 等客户端加载,并发送给 Redis 服务器,由 Redis 服务器来执行这段逻辑,这样执行的效果就是原子的了;

5. 引入 watch dog 

当我们为 key 设置了过期时间后,key 过期后会自动删除,但是此时任务还没执行完,这就会导致锁失效,其他服务器的任务来了就会重新设置 key;但如果将 key 的过期时间设置的太长,此时若服务器宕机,就会让其他服务器不能及时获取到锁;

因此就可以引入看门狗 —— 加锁服务器上的一个单独的线程,通过这个线程来完成对锁的过期时间的续约;

比如,某个 key 的过期时间是 5 秒,同时看门狗线程会每 3 秒检测一次,当第一次经过 3 秒后,看门狗线程就会判定当前任务是否已经完成:

  • 如果任务未完成,则会将过期时间重新设置为 5 秒;
  • 如果任务已经完成,则通过执行上述 lua 脚本的方式删除 key;

这就解决了锁提前失效的问题;并且即使当加锁的服务器挂了,那么此时看门狗线程也会随之挂掉,此时就不会续约,这个 key 到过期时间了就自动删除了,不会影响其他的服务器;

三、总结

以上内容只是如何实现一个简单的互斥锁,在一些实际的应用场景中,我们可能会使用一些其他特殊的锁,比如可重入锁,公平锁,读写锁等等;

关于 Redis 实现分布式锁,在实践中,我们并不会真的自己实现一个分布式锁,已经有很多的库帮我们实现好了,直接使用即可,比较 Redisson;

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

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

相关文章

如何利用小程序容器技术搭建小程序生态?

小程序,作为现代移动互联网生态中的重要基础设施,正以其独特的创新性和便捷性展现出勃勃生机。截至2021年,全网小程序的数量已经突破了700万,其中微信小程序的开发者达到了300万之多。这一数字不仅代表了小程序在技术层面的成熟度…

PKUMOD同学又双叒获奖啦~

近期王选所数据管理研究室的同学们 凭借在各自领域的卓越表现 获得了多项荣誉和奖励 让我们共赏风采~ 期待他们在未来的科研道路上 取得更加辉煌的成就 庞悦 前沿交叉学科研究院2020级博士生 荣获2024年北京大学校长奖学金 庞悦,北京大学元培学院2016级本科生&…

1000W高清内窥镜定义掏耳勺新高度,西圣Find智能挖耳勺发布!

随着生活水平的提高,人们对个人健康越来越重视。特别是在日常生活中的一些小细节上,比如掏耳朵。传统的掏耳勺只能凭感觉和经验操作,在传统的耳勺与棉签下,很容易损伤耳道,甚至引发感染。为了解决这个问题,…

Word “当前页“ 与 “前一页“ (含部分内容)间有大半页空白,删除空白方法

鼠标光标选中需要向上移的句子,右键点击“段落”,然后在跳出的窗口中按照“换行和分页”中的红色方框内取消勾选后,点击确定即可。

今晚19点,《语音和心理健康》开讲!

《2024GAS声学大讲堂—音频产业创新技术公益讲座》面向医疗健康的声音与音乐技术系列专题讲座 第五讲 将于 今晚 19点 开讲,本次邀请了 湖南大学 教授 张子兴 演讲,讲座主题:《语音和心理健康》。此次直播方式为腾讯会议、小鹅通和中国电子音…

在window上搭建docker

1、打开Hyper-V安装 在地址栏输入控制面板,然后回车 勾选Hyper-V安装,如果没有找到Hyper-V,那么请走第2步 2、如果没有Hyper-V(可选)第一步无法打开 家庭版本需要开启Hyper-V 创建一个文本文档,后缀名称为.bat.名称…

盘点2024年最新鼠标连点器推荐

电脑鼠标连点器是一种可以帮助用户自动化点击操作的小工具,广泛应用于游戏、自动化办公和测试等领域。选择一款合适的鼠标连点器能够提高工作和娱乐的效率,避免重复点击带来的疲劳。小编将为您介绍电脑鼠标连点器的产品特点、推荐几款实用的鼠标连点器并…

飞利浦的台灯值得入手吗?书客、松下多维度横评大分享!

随着生活品质的持续提升,人们对于健康的追求日益趋向精致与高端化。在这一潮流的推动下,护眼台灯以其卓越的护眼功效与便捷的操作体验,迅速在家电领域崭露头角,更成为了众多家庭书房中不可或缺的视力守护者。这些台灯以其精心设计…

中服云数字孪生平台引领工业物联仿真新纪元!

中服云数字孪生平台3.0是基于中服云物联网平台和数据中台打造的一款实时数据2D/3D集成展示监控平台。 旨在解决工业物联网数据的直观展示、实虚互动、仿真模拟、故障诊断、告警、预警、预测、实时观测、实时监控等问题。提供了数据采集、数据底座、监控逻辑、建模工具、展示互…

WSL——忘记root密码(Ubuntu)

1、问题描述 Windows下的WSL(Ubuntu)忘记了root密码,无法使用管理员权限。 2、解决方法 关闭 Ubuntu 窗口。打开 Windows 的 Powershell 或 cmd, 以 root 默认登陆 WSL。 wsl -u root 修改对应用户密码。 # xxx为要修改密码的用…

地铁车厢火灾3D模拟逃生演习减少了资源损耗和风险

在消防安全领域,为了更好地提升安全实训效果,我们在VR安全培训领域打造了多款消防安全VR模拟实训系统,不仅实现了与现实世界无异的交互操作,更在虚拟空间中超越了现实的限制,模拟出那些现实中难以搭建的复杂场景。 利用…

【学习笔记】网络设备(华为交换机)基础知识1——命令行入门知识

一、前期准备 提示:下面所有学习内容都是基于以下条件完成的 条件1.已经可以正常访问交换机的命令行接口 连接到命令行接口的方法 : ① :通过Console口本地访问 ② : 通过Telnet访问 ③ : 通过SSH访问 ④ &#xff1…

Web3 开发者入门手册:技能、工具和职业前景

原文:https://remote3.co/blog-post/how-to-become-a-web3-developer 作者:Paul Anderson 编译:TinTinLand Web3 是 2024 年科技领域最受瞩目的话题之一——Web3 令人激动的实用潜力可以跨越多个行业,早期采用者更有机会在未来…

嵌入式Linux系统编程 — 6.6 信号掩码

目录 1 信号掩码介绍 2 sigprocmas函数 3 sigsuspend函数阻塞等待信号 1 信号掩码介绍 信号掩码(Signal Mask)是操作系统中用于控制进程接收信号的一种机制。每个进程都有一个或多个信号掩码,它们定义了哪些信号在特定时间被阻塞&#xf…

探索中文文本之美:使用Python生成定制化词云

探索中文文本之美:使用Python生成定制化词云 数据可视化已成为我们理解复杂信息的关键工具。词云,作为一种流行的数据可视化形式,能够将大量文本数据中的关键词以视觉化的方式呈现,让我们迅速捕捉到文本的核心。本文将通过Python…

麒麟V10安装MinIO

1、官网下载服务端程序 2、上传至/usr/local/bin/,使用官网命令启动 chmod x minio MINIO_ROOT_USERadmin MINIO_ROOT_PASSWORDpassword ./minio server /mnt/data --console-address ":9001"后台启动 MINIO_ROOT_USERadmin MINIO_ROOT_PASSWORDpassw…

【Python好书推荐】,学习Python必备的8本书,可分享电子档!

在过去一年里,Python的热度一路飙升,国内越来越多的人选择学习Python,如今已然成为大量开发者推荐的入门编程语言和第二编程语言,而且Python还是人工智能的主要编程语言,因此,其重要性和流行度也就不言而喻…

最新榜单出炉!2024年6月AI行业微信公众号排行榜

最新榜单出炉!2024年6月AI行业微信公众号排行榜 🚀 大家好,我是猫头虎!最新的AIGCRank AI行业微信公众号排行榜已经出炉了。如果大家觉得一个一个去搜索太麻烦,没关系,我帮大家整理到了本文,今…

代谢组数据分析(十三):评估影响代谢物的重要临床指标

欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2介绍 相关性分析是通过计算两个变量之间的相关系数来评估它们之间线性关系的强度和方向。最常用的是皮尔逊相关系数(Pearson correlation coefficient),…

Appium自动化测试框架1

电脑的浏览器 手机的浏览器 手机上的app 原生的应用 纯java 手机上的app apk 移动网页应用 纯HTML CSS 手机的浏览器上 电脑的浏览器上 混合应用 java html css python代码 Appium python库 Appium 手机 都是代表本机 0.0.0.0 127.0.0.1 localhost 如何启动app 启动参…