Redis 分布式锁
什么是分布式锁
本质上就是使用一个个公共的服务器, 来记录 加锁状态.这个公共的服务器可以是 Redis, 也可以是其他组件(比如 MySQL 或者 ZooKeeper 等), 还可以是自己写的一个服务
在分布式系统中,有很多的进程(每个服务器,都是一个独立的进程)
之前的 锁,难以对分布式系统中的多个进程产生制约
分布式系统中,多个进程中间的执行顺序也是不确定的 ——> 随机性
分布式锁的基础实现
以买票为例:
现在存多个服务器节点,可能需要处理这个买票逻辑:先查询指定车次的余票,如果余票 >= 0,则设置余票值 -= 1
显然上述程序是存在“线程安全”问题的,需要加锁,否则会出现超卖现象
分布式锁,也是一组 / 一个 单独的服务器程序,给其他的服务器提供“加锁”服务
Redis 是一种典型的可以用来实现分布式锁的方案(MySQL,zookeeper ..)
引入 setnx
买票服务器在进行买票操作时,需要先加锁(往 Redis 上设置一个特殊的 key-value 完成上述买票操作,再把这个 key-value 删除掉)
其他服务器也想买票时,也去 Redis 上尝试设置 key-value,如果发现 key-value 已经存在,就认为“加锁失败”(根据情况设置 放弃 / 阻塞)
保证第一个服务器执行“查询 ——> 更新”过程中,第二个服务器不会执行“查询 ——> 更新”操作
Redis 中提供了 setnx 操作:key 不存在就设置,存在就直接失败
使用 setnx 加锁,del 解锁
上述的买票场景,使用 MySQL 事务 也是可以批量执行 查询 + 修改 操作
但是分布式系统中,要访问的共享资源不一定是 MySQL,可能是其他介质,没有事务,也可能是执行一段特定的逻辑,是通过统一的服务器完成执行操作的
引入过期时间
某个服务器,加锁成功(setnx 成功),执行后续逻辑时,程序崩溃(没有执行到解锁)
在之前的学习中,为了保证解锁操作能够执行到
C++ 使用 RAII
Java 使用 finally
但是上述的做法,只是针对进程内的锁,对分布式锁无用
进程的异常退出会导致 Redis 上设置的 key 无人删除,其他服务器无法获取 锁
可以给 key 设置过期时间,实现 key 到时自动删除
set ex nx 设置
setnx
expire 这样分开设置是不对的,必须使用上述的设置
Redis 命令之间无法保证原子性,两个命令不一定会同时成功
引入校验 id
此处的锁,就是 redis 上的普通键值对:
加锁,就是给 redis 上设置一个 key-value
解锁,就是把 redis 上这个 key-value 删除
如果代码出现bug,例如 服务器1执行加锁,服务器2执行解锁
为解决上述问题,需要引入校验机制:
1)给服务器编码,每个服务器有自己的身份标识
2)进行加锁时,设置 key-vlaue。key 对应针对哪个(车次 ..)资源进行加锁,value 存储服务器的编号,标识出当前这个锁是哪个服务器加上的,后续在解锁时就可以进行校验了
解锁时,先查询一下这个锁对应的服务器编号,判定这个编号是否是当前执行解锁操作的服务器的编号
如果是,执行 del;如果不是,就失败
引入 lua 脚本
在解锁时,先查询判定,再进行 del(此处是两步操作,不是原子的)
一个服务器内部可能是多线程的,此时可能是同一个服务器中的两个线程都在执行上述的解锁操作
线程C,在线程A GET 后,线程B DEL 之前,执行 GET
线程B 的 DEL 会把线程 B 获取的锁删除 ——> get 和 del 不是原子
使用事务,可以解决上述问题(redis 事务虽然弱,但是能够避免插队)
Lua 脚本是更好地替代
Lua 可以作为 redis 的内嵌脚本,Mysql 8支持 vimscript/python 作为内嵌语言
可以使用 lua 编写一些逻辑,把这个脚本上传到 redis 服务器上,然后就可以让客户端来控制 redis 执行上述脚本
redis 执行 lua 脚本的过程也是原子性的,相当于是执行一条命令(实际上 lua 中可以写多个命令)
if redis.call('get',KEYS[1]) == ARGV[1] thenreturn redis.call('del',KEYS[1])elsereturn 0end;
Lua 官方文档 Lua: aboutLua 的语法类似于 JS, 是一个动态弱类型的语言. Lua 的解释器一般使用 C 语言实现. Lua 语法简单精炼, 执行速度快, 解释器也比较轻量(Lua 解释器的可执行程序体积只有 200KB 左右).因此 Lua 经常作为其他程序内部嵌入的脚本语言. Redis 本身就支持 Lua 作为内嵌脚本
引入看门狗
在加锁时,给 key 设置的时间不一定满足实际情况:
设置的时间过短,业务逻辑还没执行完,就释放锁了
设置的时间过长,锁释放不及时,业务阻塞
更好地解决方式是“动态续约”:
初始情况下,设置一个过期时间 1s,就提前在还剩 300ms 时,如果业务已经完成,直接通过 lua 脚本的方式,释放锁;如果当前任务还没执行完,就把过期时间再续上 1s,等过期时间又快到了,任务还没执行完,再续时间 ..
如果服务器崩溃,自然就没有人续约了,锁 也能在较短的时间内被自动释放
动态续约,往往需要业务服务器这边有一个专门的线程负责(看门狗 watch dog)
redlock 算法
为了确保高可用性,需要通过一系列的“预案演习”
哨兵 ——> 在分布式锁场景中,涉及的数据量不大
进行加锁,就是把 key 设置到主节点上
如果主节点挂了,有哨兵自动的把从节点升级成主节点,进一步保证锁的可用性
主节点和从节点之间的数据同步,是存在延时的
可能主节点收到 set 请求,还没来得及同步给从节点,主节点就先挂了
及时从节点升级成主节点,刚才的加锁对应的数据也是形同虚设的,其他服务器仍然可以进行加锁(新的主节点不包含刚才的 key)——>
引入多组 redis 节点,每组 redis 节点都包含一个主节点和若干个从节点(组合组之间存储的数据都是一致的,相互之间是“备份”关系)
加锁的时候,按照一定的顺序针对多组 redis 都进行加锁
如果某个节点挂了,继续给下个节点加锁
如果写入 key 成功的节点个数超过总数的一半,就认为加锁成功
同理,进行解锁时,也会把上述过程都设置一遍解锁
上述介绍的只是一个“互斥锁”
基于 redis 也可以实现以下锁的特性:
读写锁,公平锁,可重入锁 ..
相关文章:
Redis 分布式锁
什么是分布式锁 在一个分布式的系统中, 也会涉及到多个节点访问同一个公共资源的情况. 此时就需要通过 锁 来做互斥控制, 避免出现类似于 "线程安全" 的问题 而 java 的 synchronized 或者 C 的 std::mutex, 这样的锁都是只能在当前进程中生效, 在分布式的这种多个进…...
Redis爆肝总结
一、基础 1.介绍 本质上是一个Key-Value类型的内存数据库,数据的加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。 速度快的根本原因 纯内存操作,性能非常出色,每秒可以处理超过10万次读写操作&a…...
Qt模块化架构设计教程 -- 轻松上手插件开发
概述 在软件开发领域,随着项目的增长和需求的变化,保持代码的可维护性和扩展性变得尤为重要。一个有效的解决方案是采用模块化架构,尤其是利用插件系统来增强应用的功能性和灵活性。Qt框架提供了一套强大的插件机制,可以帮助开发者轻松实现这种架构。 模块化与插件系统 模…...
[项目总结] 抽奖系统项目技术应用总结
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
【运维】基于Python打造分布式系统日志聚合与分析利器
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在分布式系统中,日志数据分散在多个节点,管理和分析变得复杂。本文详细介绍如何基于Python开发一个日志聚合与分析工具,结合Logstash和F…...
MySql(基础)
表名建议用 反引号 包裹(尤其是表名包含特殊字符或保留字时),但如果表名是普通字符串(如 user),可以省略。 注释(COMMENT 姓名) 数据库 1.查看数据库:show databases…...
怎样选择成长股 读书笔记(一)
文章目录 第一章 成长型投资的困惑一、市场不可预测性的本质困惑二、成长股的筛选悖论三、管理层评估的认知盲区四、长期持有与估值波动的博弈五、实践中的认知升级路径总结:破解困惑的行动框架 第二章 如何阅读应计制利润表一、应计制利润表的本质与核心原则1. 权责…...
系统思考:个人与团队成长
四年前,我交付的系统思考项目,今天学员的反馈依然深深触动了我。 我常常感叹,系统思考不仅仅是一场培训,更像是一场持续的“修炼”。在这条修炼之路上,最珍贵的,便是有志同道合的伙伴们一路同行࿰…...
并行发起http请求
1. 使用 axios Promise.all <template><input type"file" multiple change"handleFileUpload" /> </template><script> import axios from axios;export default {methods: {async handleFileUpload(event) {const files event…...
【数据结构入门训练DAY-31】组合的输出
本文介绍了如何使用深度优先搜索(DFS)算法解决数的组合问题。题目要求从1到n的自然数中选取r个数,输出所有可能的组合,并按字典顺序排列。文章详细描述了解题思路,包括建立数组存储数字、使用DFS递归处理候选数、以及如…...
leetcode0815. 公交路线-hard
1 题目: 公交路线 官方标定难度:难 给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。 例如,路线 routes[0] [1, 5, 7] 表示第 0 辆公…...
花朵识别系统Python+深度学习+卷积神经网络算法+TensorFlow+人工智能
一、介绍 花朵识别系统。本系统采用Python作为主要编程语言,基于TensorFlow搭建ResNet50卷积神经网络算法模型,并基于前期收集到的5种常见的花朵数据集(向日葵、玫瑰、蒲公英、郁金香、菊花)进行处理后进行模型训练,最…...
LLM 论文精读(四)LLM Post-Training: A Deep Dive into Reasoning Large Language Models
这是一篇2025年发表在arxiv中的LLM领域论文,是一篇非常全面的综述类论文,介绍了当前主流的强化学习方法在LLM上的应用,文章内容比较长,但建议LLM方面的从业人员反复认真阅读。 写在最前面 为了方便你的阅读,以下几点的…...
网址为 http://xxx:xxxx/的网页可能暂时无法连接,或者它已永久性地移动到了新网址
这是由于浏览器默认的非安全端口所导致的,所谓非安全端口,就是浏览器出于安全问题,会禁止一些网络浏览向外的端口。 避免使用6000,6666这样的端口 6000-7000有很多都不行,所以尽量避免使用这个区间 还有在云服务器中,…...
【C++】16.继承
C三大特性:封装,继承,多态 在前面的章节中,我们讲过了封装,也就是通过类和访问修饰符来进行封装。 接下来我们就来认识一下新的特性——继承 1. 继承的概念及定义 1.1 继承的概念 继承(inheritance)机制是面向对…...
LlamaIndex 第七篇 结构化数据提取
大型语言模型(LLMs)在数据理解方面表现出色,这也促成了它们最重要的应用场景之一:能够将常规的人类语言(我们称之为非结构化数据)转化为特定的、规范的、可被计算机程序处理的格式。我们将这一过程的输出称…...
PHP API安全设计四要素:构建坚不可摧的接口防护体系
引言:API安全的重要性 在当今前后端分离和微服务架构盛行的时代,API已成为系统间通信的核心枢纽。然而,不安全的API可能导致: 数据泄露:敏感信息被非法获取篡改风险:传输数据被中间人修改重放攻击&#x…...
英语16种时态
时态应用场合格式例子一般现在时表示经常、反复发生的动作,客观事实或普遍真理主语 动词原形(第三人称单数作主语时动词加 -s/-es)The sun rises in the east.一般过去时表示过去某个时间发生的动作或存在的状态主语 动词的过去式I visited…...
使用 goaccess 分析 nginx 访问日志
介绍 goaccess 是一个在本地解析日志的工具, 可以直接在命令行终端环境中使用 TUI 界面查看分析结果, 也可以导出为更加丰富的 HTML 页面. 官网: https://goaccess.io/ 下载安装 常见的 Linux 包管理器中都包含了 goaccess, 直接安装就行. 以 Ubuntu 为例: sudo apt instal…...
什么是中央税
中央税(又称国家税)是指由中央政府直接征收、管理和支配的税种,其收入全额纳入中央财政,用于保障国家层面的财政支出和宏观调控。中央税通常具有税基广泛、收入稳定、涉及国家主权或全局性经济调控的特点。 --- 中央税的核心特征…...
AI Agent(10):个人助手应用
引言 本文聚焦AI Agent在个人助手领域的应用,探讨其如何在个人生产力提升、健康与生活管理、学习与教育辅助以及娱乐与社交互动四个方面,为用户创造价值并解决实际问题。 AI个人助手正从简单的指令执行者逐渐发展为具有自主性、适应性和个性化能力的智能伙伴。这一转变不仅…...
力扣70题解
记录 2025.5.8 题目: 思路: 1.初始化:p 和 q 初始化为 0,表示到达第 0 级和第 1 级前的方法数。r 初始化为 1,表示到达第 1 级台阶有 1 种方法。 2.循环迭代:从第 1 级到第 n 级台阶进行迭代: p 更新为前…...
2025御网杯wp(web,misc,crypto)
文章目录 miscxor10图片里的秘密被折叠的显影图纸 Cryptoeasy_rsagift**1. 礼物数学解析****最终答案** 草甸方阵的密语easy-签到题baby_rsa webYWB_Web_xffYWB_Web_未授权访问easywebYWB_Web_命令执行过滤绕过反序列化 misc xor10 ai一把梭 根据题目中的字符串和提示&#…...
【深度学习】将本地工程上传到Colab运行的方法
1、将本地工程(压缩包)上传到一个新的colab窗口:如下图中的 2.zip,如果工程中有数据集,可以删除掉。 2、解压压缩包。 !unzip /content/2.zip -d /content/2 如果解压出了不必要的文件夹可以递归删除: #…...
多模态大语言模型arxiv论文略读(六十九)
Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文标题:Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文作者:Yue Zha…...
Lua再学习
因为实习的项目用到了Lua,所以再来深入学习一下 函数 函数的的多返回值 Lua中的函数可以实现多返回值,实现方法是再return后列出要返回的值的列表,返回值也可以通过变量接收到,变量不够也不会影响接收对应位置的返回值 Lua中传…...
Linux计划任务与进程
at 命令使用方法 at 命令可在指定时间执行任务,适用于一次性任务调度。以下是基本用法: 安装 atd 服务(如未安装) # Debian/Ubuntu sudo apt-get install at# CentOS/RHEL sudo yum install at启动服务 sudo systemctl start atd…...
JavaEE--文件操作和IO
目录 一、认识文件 二、 树型结构组织和目录 三、文件路径 1. 绝对路径 2. 相对路径 四、文件类型 五、文件操作 1. 构造方法 2. 方法 六、文件内容的读写——数据流 1. InputStream概述 2. FileInputStream概述 2.1 构造方法 2.2 示例 3. OutputStream概述 3.…...
k8s的节点是否能直接 curl Service 名称
在 Kubernetes 中,节点(Node)默认情况下不能直接通过 Service 的 DNS 名称(如 my-svc.default.svc.cluster.local)访问 Service。以下是详细分析和解决方案: 1. 默认情况下节点无法解析 Service 的 DNS 名…...
Mask-aware Pixel-Shuffle Down-Sampling (MPD) 下采样
来源 简介:这个代码实现了一个带有掩码感知的像素重排下采样模块,主要用于图像处理任务(如图像修复或分割)。 论文题目:HINT: High-quality INpainting Transformer with Mask-Aware Encoding and Enhanced Attentio…...
本贴会成为记录贴
这几天有些心力交瘁了 一方面带着对互联网下行的伤心,一方面是对未来的担忧 一转眼好像就是20 21那个 可以在宿舍肆意玩手机 大学生活 可是我不小了 是个26岁的人了 时间很快 快的就好像和自己开了一个玩笑 我以为可以找到一个自己足够喜欢的 可爱的人 可是我没有 …...
redis数据结构-04 (HINCRBY、HDEL、HKEYS、HVALS)
哈希操作:HINCRBY、HDEL、HKEYS、HVALS Redis 中的哈希功能极其丰富,让您能够以类似于编程语言中对象的方式存储和检索数据。本课将深入探讨具体的哈希操作,这些操作为操作以下结构中的数据提供了强大的工具: HINCRBY 、 HDEL 、…...
python 写一个工作 简单 番茄钟
1、图 2、需求 番茄钟(Pomodoro Technique)是一种时间管理方法,由弗朗西斯科西里洛(Francesco Cirillo)在 20 世纪 80 年代创立。“Pomodoro”在意大利语中意为“番茄”,这个名字来源于西里洛最初使用的一个…...
复现MAET的环境问题(自用)
我的配置是3090,CUDA Version: 12.4 配置环境时总有冲突,解决好的环境如下 如果你的配置也是CUDA12.4,可以把下面的配置信息保存成 environment.yml 文件 然后执行下面的代码创建环境即可 conda env export > environment.yml name:…...
PDF2zh插件在zotero中安装并使用
1、首先根据PDF2zh说明文档,安装PDF2zh https://github.com/guaguastandup/zotero-pdf2zh/tree/v2.4.0 我没有使用conda,直接使用pip安装pdf2zh (Python版本要求3.10 < version <3.12) pip install pdf2zh1.9.6 flask pypd…...
第二十三节:图像金字塔- 图像金字塔应用 (图像融合)
一、引言:视觉信息的层次化表达 在数字图像处理领域,图像金字塔(Image Pyramid)作为一种多尺度表示方法,自20世纪80年代提出以来,始终在计算机视觉领域扮演着关键角色。这种将图像分解为不同分辨率层次的结构化表示方法,完美地模拟了人类视觉系统对场景的多尺度感知特性…...
一种混沌驱动的后门攻击检测指标
摘要 人工智能(AI)模型在各个领域的进步和应用已经改变了我们与技术互动的方式。然而,必须认识到,虽然人工智能模型带来了显著的进步,但它们也存在固有的挑战,例如容易受到对抗性攻击。目前的工作提出了一…...
LeetCode 高频题实战:如何优雅地序列化和反序列化字符串数组?
文章目录 摘要描述题解答案题解代码分析编码方法解码方法 示例测试及结果时间复杂度空间复杂度总结 摘要 在分布式系统中,数据的序列化与反序列化是常见的需求,尤其是在网络传输、数据存储等场景中。LeetCode 第 271 题“字符串的编码与解码”要求我们设…...
leetcode 15. 三数之和
题目描述 代码: class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());int len nums.size();int left 0;int right 0;vector<vector<int>> res;for(int i 0;i <len…...
HTML难点小记:一些简单标签的使用逻辑和实用化
HTML难点小记:一些简单标签的使用逻辑和实用化 jarringslee 文章目录 HTML难点小记:一些简单标签的使用逻辑和实用化简单只是你的表象标签不是随便用的<div> 滥用 vs 语义化标签的本质嵌套规则的隐藏逻辑SEO 与可访问性的隐形关联 暗藏玄机的表单…...
Linux : 31个普通信号含义
Linux : 31个普通信号 信号含义特殊的两个信号 信号含义 信号编号信号名信号含义1SIGHUP如果终端接口检测到一个连接断开,则会将此信号发送给与该终端相关的控制进程,该信号的默认处理动作是终止进程。2SIGINT当用户按组合键(一般…...
软件测试都有什么???
文章目录 一、白盒测试(结构测试)二、黑盒测试(功能测试)三、灰盒测试四、其他测试类型五、覆盖准则对比六、应用场景 软件测试主要根据测试目标、技术手段和覆盖准则进行分类。分为白盒测试、黑盒测试、灰盒测试及其他补充类型 一…...
LangGraph框架中针对MCP协议的变更-20250510
MCP(Model Context Protocol)的出现为AI Agent与外部工具及数据源的集成提供了标准化接口,而LangGraph作为基于LangChain的智能体开发框架,在MCP协议的影响下也进行了适配性调整,主要体现在工具调用、异步交互和多步推…...
YashanDB(崖山数据库)V23.4 LTS 正式发布
2024年回顾 2024年11月我们受邀去深圳参与了2024国产数据库创新生态大会。在大会上崖山官方发布了23.3。这个也是和Oracle一样采用的事编年体命名。 那次大会官方希望我们这些在一直从事在一线的KOL帮助产品提一些改进建议。对于这样的想法,我们都是非常乐于合作…...
二、transformers基础组件之Tokenizer
在使用神经网络处理自然语言处理任务时,我们首先需要对数据进行预处理,将数据从字符串转换为神经网络可以接受的格式,一般会分为如下几步: - Step1 分词:使用分词器对文本数据进行分词(字、字词);- Step2 构建词典:根据数据集分词的结果,构建…...
git 报错:错误:RPC 失败。curl 28 Failed to connect to github.com port 443 after 75000
错误:RPC 失败。curl 28 Failed to connect to github.com port 443 after 75000 ms: Couldnt connect to server致命错误:在引用列表之后应该有一个 flush 包 方法一: 直接换一个域名:把 git clone https://github.com/zx59530…...
软考 系统架构设计师系列知识点之杂项集萃(56)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(55) 第91题 商业智能关注如何从业务数据中提取有用的信息,然后采用这些信息指导企业的业务开展。商业智能系统主要包括数据预处理、建立()、数据分…...
数据库的脱敏策略
数据库的脱敏策略:就是屏蔽敏感的数据 脱敏策略三要求: (1)表对象 (2)生效条件(脱敏列、脱敏函数) (3)二元组 常见的脱敏策略规则: 替换、重排、…...
Lora原理及实现浅析
Lora 什么是Lora Lora的原始论文为《LoRA: Low-Rank Adaptation of Large Language Models》,翻译为中文为“大语言模型的低秩自适应”。最初是为了解决大型语言模在进行任务特定微调时消耗大量资源的问题;随后也用在了Diffusion等领域,用于…...
力扣热题100之合并两个有序链表
题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 代码 方法一:新建一个链表 这里就先随便新建一个节点作为一个链表的头节点,然后每次遍历都将小的那个节点放入这个链表,遍历完一…...