redis深度历险 千帆竞发 —— 分布式锁
分布式应用进行逻辑处理时经常会遇到并发问题。
比如一个操作要修改用户的状态,修改状态需要先读出用户的状态,在内存里进行修改,改完了再存回去。如果这样的操作同时进行了,就会出现并发问题,因为读取和保存状态这两个操作不是原子的。(Wiki 解释:所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch 线程切换。)
这个时候就要使用到分布式锁来限制程序的并发执行。Redis 分布式锁使用非常广泛,它是面试的重要考点之一,很多同学都知道这个知识,也大致知道分布式锁的原理,但是具体到细节的使用上往往并不完全正确。
1 分布式锁
1.1 步骤1,向 Redis 节点发送命令,请求锁。
分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后再试。
占坑一般是使用 setnx(set if not exists) 指令,只允许被一个客户端占坑。先来先占, 用完了,再调用 del 指令释放茅坑。
127.0.0.1:6379> setnx lock:codehole true
(integer) 1
127.0.0.1:6379> .. do something critical ..
127.0.0.1:6379> .. do something critical ..
127.0.0.1:6379> del lock:codehole
(integer) 1
127.0.0.1:6379>
但是有个问题,如果逻辑执行到中间出现异常了,可能会导致 del 指令没有被调用,这样就会陷入死锁,锁永远得不到释放。
于是我们在拿到锁之后,再给锁加上一个过期时间,比如 5s,这样即使中间出现异常也可以保证 5 秒之后锁会自动释放。
127.0.0.1:6379> setnx lock:codehole true
(integer) 1
127.0.0.1:6379> expire lock:codehole 5
(integer) 1
127.0.0.1:6379>.. do something critical ..
127.0.0.1:6379>.. do something critical ..
127.0.0.1:6379> del lock:codehole
(integer) 1
但是以上逻辑还有问题。如果在setnx和 expire 之间服务器进程突然挂掉了,可能是因为机器掉电或者是被人为杀掉的,就会导致expire 得不到执行,也会造成死锁。
这种问题的根源就在于setnx和 expire是两条指令而不是原子指令。如果这两条指令可以一起执行就不会出现问题。也许你会想到用Redis事务来解决。但是这里不行,因为expire是依赖于 setnx的执行结果的,如果 setnx没抢到锁, expire是不应该执行的。事务里没有 if-else 分支逻辑,事务的特点是一口气执行,要么全部执行要么一个都不执行。
为了解决这个疑难,Redis开源社区涌现了一堆分布式锁的 library,专门用来解决这个问题。实现方法极为复杂,小白用户一般要费很大的精力才可以搞懂。如果你需要使用分布式锁,意味着你不能仅仅使用Jedis或者redis-py就行了,还得引入分布式锁的 library。
为了治理这个乱象,Redis 2.8 版本中作者加入了 set 指令的扩展参数,使得 setnx 和expire 指令可以一起执行,彻底解决了分布式锁的乱象。从此以后所有的第三方分布式锁library 可以休息了。
127.0.0.1:6379> set lock:codehole true ex 5 nx
OK
127.0.0.1:6379>.. do something critical ..
127.0.0.1:6379>.. do something critical ..
127.0.0.1:6379> del lock:codehole
(integer) 0
setnx 和 expire 组合在一起的原子指令,它就是分布式锁的奥义所在。
下面解释下各参数的意义。
set lock:codehole true ex 5 nx
SET lock_name my_random_value EX 30000 NX
- lock_name,即锁名称,这个名称应是公开的,在分布式环境中,对于某一确定的公共资源,所有争用方(客户端)都应该知道对应锁的名字。对于 Redis 而言,lock_name 就是 Key-Value 中的 Key,具有唯一性。
- my_random_value是由客户端生成的一个随机字符串,它要保证在足够长的一段时间内,且在所有客户端的所有获取锁的请求中都是唯一的,用于唯一标识锁的持有者。
- NX 表示只有当 lock_name(key) 不存在的时候才能 SET成功,从而保证只有一个客户端能获得锁,而其它客户端在锁被释放之前都无法获得锁。
- EX 30000 表示这个锁节点有一个 30秒的自动过期时间(目的是为了防止持有锁的客户端故障后,无法主动释放锁而导致死锁,因此要求锁的持有者必须在过期时间之内执行完相关操作并释放锁)。
1.2 步骤2,如果步骤 1 的命令返回成功,则代表获取锁成功,否则获取锁失败。
对于一个拥有锁的客户端,释放锁流程如下。
(1)向 Redis 节点发送命令,获取锁对应的 Value,代码如下:
GET lock_name
(2)如果查询回来的 Value 和客户端自身的 my_random_value 一致,则可确认自己是锁的持有者,可以发起解锁操作,即主动删除对应的 Key,发送命令:
DEL lock_name
通过 Redis-cli 执行上述命令,显示如下:
100.X.X.X:6379> set lock_name my_random_value NX EX 30000
OK
100.X.X.X:6379> get lock_name
"my_random_value"
100.X.X.X:6379> del lock_name
(integer) 1
100.X.X.X:6379> get lock_name
(nil)
相关文章:
redis深度历险 千帆竞发 —— 分布式锁
分布式应用进行逻辑处理时经常会遇到并发问题。 比如一个操作要修改用户的状态,修改状态需要先读出用户的状态,在内存里进行修改,改完了再存回去。如果这样的操作同时进行了,就会出现并发问题,因为读取和保存状态这两个…...
C#根据中文首字母排序
第一种方式: 这种方式会受制于服务器的区域和语言设置。 1.首先添加一个排序类ChineseNameComparer public class ChineseNameComparer : IComparer<string> {public int Compare(string x, string y){if (x null || y null)return 0;var xFirstChar x.Su…...
仪表基础知识培训
压力传感器:E+H PMX5x/FMX5x 一、安装:安装注意事项: 1、水平安装时仪表的呼吸孔(1)需要向下安装,并远离污染物。 2、请勿用坚硬的物体擦拭或接触膜片。 3、请勿安装在水泵的入口和搅拌叶附近 二、供电、接线、信号、:二线制,仪表输出4-20mA 三、量程:设置最大最小量程…...
无涯教程-JavaScript - PI函数
描述 PI函数返回数字3.14159265358979,数学常数pi,精确到15位数字。 语法 PI ()争论 PI函数语法没有参数。 适用性 Excel 2007,Excel 2010,Excel 2013,Excel 2016 Example JavaScript 中的 PI函数 - 无涯教程网无涯教程网提供描述PI函数返回数字3.14159265358979,数学常…...
前端防抖和节流
前端防抖和节流 概述 防抖: 防止抖动,个人字面理解此处防的不是页面的抖动,而是用户手抖。为了防止用户快速且频繁的触发事件而导致多次执行事件函数,这样的场景有很多,比如监听滚动、鼠标移动事件onmousemove、频繁…...
[pai-diffusion]pai的easynlp的clip模型训练
EasyNLP带你玩转CLIP图文检索 - 知乎作者:熊兮、章捷、岑鸣、临在导读随着自媒体的不断发展,多种模态数据例如图像、文本、语音、视频等不断增长,创造了互联网上丰富多彩的世界。为了准确建模用户的多模态内容,跨模态检索是跨模态…...
期权如何交易?期权如何做模拟交易?
买卖期权的第一步就是要有期权账户,国内的期权品种有商品期权和ETF期权以及股指期权,每种的开户方式和要求都不同,下文为大家介绍期权如何交易?期权如何做模拟交易? 一、期权交易需要开立一个期权账户,可以…...
【新书推荐】大模型赛道如何实现华丽的弯道超车 —— 《分布式统一大数据虚拟文件系统 Alluxio原理、技术与实践》
文章目录 大模型赛道如何实现华丽的弯道超车 —— AI/ML训练赋能解决方案01 具备对海量小文件的频繁数据访问的 I/O 效率02 提高 GPU 利用率,降低成本并提高投资回报率03 支持各种存储系统的原生接口04 支持单云、混合云和多云部署01 通过数据抽象化统一数据孤岛02 …...
Calendar对象获取当前周的bug
项目场景: 双周项目管理,需要获取当前周为一年之中的第几周,原先的代码是用Calendar对象,先用setTime()把当前时间传入,再用get(3)获取一年中的第几周 问题描述 实际发…...
嵌入式环境buildroot的espeak配置与编译
1、在buildroot目录下输入make menuconfig 2、选择Target packages 3、选择Audio and video applications 4、选择espeak、选择alsa via portaudio (新版嵌入式linux一般都是用alsa音频驱动) 5、配置portaudio 选择Library 6、选择Audio/Sound 7、选择…...
物理机环境搭建-linux部署nginx
1、安装nginx部署所需依赖 yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel2、安装nginx包 wget http://nginx.org/download/nginx-1.8.0.tar.gz 如果没有wget可以安装一下 yum install -y wget下载完成后可以在/usr/local/下放置tar包…...
删除安装Google Chrome浏览器时捆绑安装的Google 文档、表格、幻灯片、Gmail、Google 云端硬盘、YouTube网址链接(Mac)
删除安装Google Chrome浏览器时捆绑安装的Google 文档、表格、幻灯片、Gmail、Google 云端硬盘、YouTube网址链接(Mac) Mac mini操作系统,安装完 Google Chrome 浏览器以后,单击 启动台 桌面左下角的“显示应用程序”,我们发现捆绑安装了 Goo…...
硬件故障诊断:快速定位问题
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
IP代理与加速器:理解它们的区别与共同点
在网络使用过程中,我们经常会遇到需要提高访问速度或保护隐私的需求。IP代理和加速器都是常见的应对方案,但它们在工作原理和应用场景上存在一些区别。本文将为您深入探讨IP代理和加速器的异同,帮助您更好地理解它们的作用和适用情况…...
Java中List转字符串的方法
一、使用String.join方法 在Java 8之后,String类增加了一个静态方法join(),可以方便地将列表中的元素连接成字符串。 // 创建List List<String> list Arrays.asList("Google", "Baidu", "Taobao"); // 以逗号分隔…...
PyTorch实战:实现MNIST手写数字识别
前言 PyTorch可以说是三大主流框架中最适合初学者学习的了,相较于其他主流框架,PyTorch的简单易用性使其成为初学者们的首选。这样我想要强调的一点是,框架可以类比为编程语言,仅为我们实现项目效果的工具,也就是我们…...
【计算机网络】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)
TCP协议 1.连接管理机制2.再谈WAIT_TIME状态2.1理解WAIT_TIME状态2.2解决TIME_WAIT状态引起的bind失败的方法2.3监听套接字listen第二个参数介绍 3.滑动窗口3.1介绍3.2丢包情况分析 4.流量控制5.拥塞控制5.1介绍5.2慢启动 6.捎带应答、延时应答 1.连接管理机制 正常情况下&…...
springboot整合sentinel完成限流
1、直入正题,下载sentinel的jar包 1.1 直接到Sentinel官网里的releases下即可下载最新版本,Sentinel官方下载地址,直接下载jar包即可。不过慢,可能下载不下来 1.2 可以去gitee去下载jar包 1.3 下载完成后,进行打包…...
signal(SIGPIPE, SIG_IGN)
linux查看signal常见信号。 [rootplatform:]# kill -l1) HUP2) INT3) QUIT4) ILL5) TRAP6) ABRT7) BUS8) FPE9) KILL 10) USR1 11) SEGV 12) USR2 13) PIPE 14) ALRM 15) TERM 16) STKFLT 17) CHLD 18) CONT 19) STOP 20) TSTP 21) TTIN 22) TTOU 23) URG 24) XCPU 25) XFSZ 2…...
GAN学习笔记
1.原始的GAN 1.1原始的损失函数 1.1.1写法1参考1,参考2 1.1.2 写法2 where, G Generator D Discriminator Pdata(x) distribution of real data P(z) distribution of generator x sample from Pdata(x) z sample from P(z) D(x) Discriminator network G…...
layui框架学习(45: 工具集模块)
layui的工具集模块util支持固定条、倒计时等组件,同时提供辅助函数处理时间数据、字符转义、批量事件处理等操作。 util模块中的fixbar函数支持设置固定条(2.7版本的帮助文档中叫固定块),是指固定在页面一侧的工具条元素&…...
车道检测:Decoupling the Curve Modeling and Pavement Regression for Lane Detection
论文作者:Wencheng Han,Jianbing Shen 作者单位:University of Macau 论文链接:http://arxiv.org/abs/2309.10533v1 内容简介: 1)方向:车道检测 2)应用:车道检测 3)…...
【扩散生成模型】Diffusion Generative Models
提出扩散模型思想的论文: 《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》理解 扩散模型综述: “扩散模型”首篇综述论文分类汇总,谷歌&北大最新研究 理论推导、代码实现: What are Diffusion Models?…...
美联储加息步伐“暂停”!BTC凌晨力守27000美元!
美东时间9月20日下午,美联储宣布放缓加息步伐,将联邦基金利率目标维持在5.25%至5.50%的区间不变,保持在22年来的最高点,符合市场预期。 在最新的FOMC声明中,美联储表示最近的指标表明,经济活动一直在稳步扩…...
微信小程序与idea后端如何进行数据交互
交互使用的其实就是调用的req.get(url)方法 进行路径访问,你要先保证自己的springboot项目已经成功运行了: 如下: 如何交互的? 微信小程序:如下为index.js页面 在onLoad()事件中调用方法Project.findAllCities() 要…...
Java 学习路线分享 maven 是什么?
Maven 是一款基于 Java 平台的项目管理和整合工具,它将项目的开发和管理过程抽象成一个项目对象模型(POM)。开发人员只需要做一些简单的配置,Maven 就可以自动完成项目的编译、测试、打包、发布以及部署等工作。 Maven 是使用 Ja…...
实战演练 | Navicat 常用功能之转储与运行 SQL 文件
数据库管理工作中,"转储 SQL 文件"和"运行 SQL 文件"是两个极为常见操作。一般来说,用户使用数据库管理工具或命令行工具来完成。Navicat 管理开发工具中的“转储 SQL 文件”和“运行 SQL 文件”功能具有直观易用的界面、多种文件格…...
MySQL的备份与恢复
备份与恢复 一、备份1.1 数据备份的必要性1.2 数据备份分类1.2.1 物理备份1.2.2 逻辑备份 1.3 数据库备份策略1.4 常用的备份方法和工具1.5 数据库上云迁移 二、MySQL完全备份2.1 简介2.2 物理冷备份与恢复2.2.1 物理冷备份2.2.2 解压恢复 2.3 mysqldump备份与恢复1)…...
Python中的函数未定义的错误
前言: 嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 通过这个解释,我们将了解当Python程序显示类似NameError: name ‘’ is not defined的错误时,即使该函数存在于脚本中&…...
AG35学习笔记(二):安装编译SDK、CMakeLists编译app、Scons编译server
目录 一、概述二、安装SDK2.1 网盘SDK - 权限不够2.2 bj41 - 需要交叉source2.3 mullen - relocate_sdk.py路径有误 三、编译SDK3.1 /bin/sh: 1: gcc: not found3.2 curses.h: No such file or directory 四、CMakeLists - 编译app4.1 cmake - 项目构建4.2 make - 项目编译4.3 …...
关于工装设计的网站/公司怎么建立自己的网站
今天又搞了下jsp servlet 的代码样例,感觉虽然搭了好多次,可是每次还是不记得那些参数,都要去网上搜索,索性自己把这次的简单demo给记录下来,供下次使用的时候直接复制吧。这个web逻辑 input.jsp ---->ReportServle…...
wordpress如何上传图片/石家庄最新疫情
文字加工常用于模具标记、零件装饰、简单文字雕刻等,如图6.1所示。文字加工一般在零件精加工之后进行。由于加工的刀具直径很小,很容易折断。因此文字加工切削量少,需要在转速高达10000~30000r/min的高速机或雕刻机上才能以较短的时间完成。文…...
php做的网站怎么加密/百度seo排名优化公司
Linux中的配置文件一般为:纯文本格式 XML格式Bash配置文件:1) profile类:交互式登录用户/etc/profile(它还包含-/etc/profile.d/*.sh对全局用户有效)--~/.bash_profile(仅对某个用户有效,编辑它还可以针对特定用户在登录时显示…...
移动端购物网站建设/免费网站seo优化
问题概述问题1:H5 web 移动端 输入框, 键盘唤起后fixed定位好的元素跟随页面滚动了起来… fixed属性失效了!满屏任性横飞, 如下图:问题2:有几后来含些在到气时按式近篇来又的方浏消风第三方输入法的ios机还会出现键盘弹出延迟,导致…...
党建类网站如何建设/劳动局免费培训电工
1. 首先下载microsoft installer clean up进行卸载操作。 2. 之后安装可能遇到如下问题:安装Sql Server 2008 R2 企业版出现错误提示无法继续安装,错误提示为: Could not open key: UNKNOWN\Components\7ABFE44842C12B390AF18C3B9B1A1EE8\000…...
做网站上传照片的尺寸/2020新闻大事件摘抄
在linux下输入 crontab -e 命令时,发现 no crontab for root - using an empty one/bin/sh: /usr/bin/vi: No such file or directorycrontab: "/usr/bin/vi" exited with status 127 后来发现是没有下载vi编辑器,所以需要把默认编辑器改成vim…...