Redis(2):Redis + Lua为什么可以实现原子性

Redis 作为一款高性能的键值对存储数据库,与 Lua 脚本相结合,为实现原子性操作提供了强大的解决方案本文将深入探讨 Redis + Lua 实现原子性的相关知识

原子性概念的厘清

在探讨 Redis + Lua 的原子性之前,我们需要明确原子性的概念。通常我们提及的原子性,多是指关系型数据库(如 MySQL)ACID 特性中的 Atomicity(原子性)。在 ACID 语境下,原子性要求事务中的所有操作要么全部成功执行,要么全部失败回滚。

以常见的银行转账为例,当账户 A 向账户 B 转账 100 元时,原子性确保账户 A 减去 100 元的同时,账户 B 必须增加 100 元。若账户 A 减少了 100 元,但账户 B 未增加 100 元,该操作就不具备原子性,需要回滚,将账户 A 减少的 100 元加回去。这一概念是我们理解数据操作完整性的基础。

Lua 原子性在 Redis 中的体现

Lua 本身只是一种脚本语言,它并未直接提供原子性支持,通常被嵌入到像 Redis 这样的宿主程序中运行。在 Redis 环境里,执行 Lua 脚本的原子性意味着整个 Lua 脚本在执行期间,不会被其他客户端的命令打断。这就保证了在执行 Lua 脚本时,Redis 会将其视为一个不可分割的整体来处理,不会受到其他并发操作的干扰。

Redis 的事务机制

Redis 的事务由 MULTI/EXEC 两个核心命令完成,同时 WATCH/DISCARD 两个命令为其增添了 CAS(Compare - And - Swap)乐观锁机制。不过需要注意的是,Redis 的事务与关系型数据库(如 MySQL)遵循的 ACID 事务不同,它并不支持回滚。

Redis 执行 Lua 的方式

Redis 通过原生命令(如 EVAL/EVALSHA 命令)来执行 Lua 脚本。在编写 Lua 脚本时,开发者需要特别留意 redis.call () 和 redis.pcall () 这两个命令的区别。

  • redis.call():用于执行 Redis 的命令。一旦命令执行出错,它会阻断整个脚本的执行,并将错误信息返回给客户端。这种特性适合在需要严格保证命令执行成功的场景中使用,若某个关键命令失败,整个脚本不应继续执行。
  • redis.pcall():同样用于执行 Redis 的命令,但当命令执行出错时,它不会阻断脚本的执行,而是在内部捕获错误,并继续执行后续的命令。这种方式适用于一些对部分命令失败有一定容忍度,希望脚本尽可能完整执行的场景。

Redis 部署方式对事务结果的影响

Redis 的部署方式在一定程度上影响着 Lua 脚本执行的原子性结果。

  • 单机部署:无论 Lua 脚本中操作的 key 是否为同一个,单机部署的 Redis 都能保证原子性。因为在单机环境下,所有操作都是在同一个进程中顺序执行,不存在并发干扰的问题。
  • 主从部署:Redis 的主从复制旨在将主节点的数据同步到从节点,以维持数据一致性。由于所有写操作都在主节点进行,所以无论 Lua 脚本操作的 key 是否相同,都能保证原子性。主节点按顺序执行 Lua 脚本,从节点则通过复制机制保持数据同步。
  • Cluster 部署:情况相对复杂。如果 Lua 脚本操作的是同一个 key,能保证原子性;但如果操作的 key 不同,这些 key 可能被 hash 到不同的 slot,也可能 hash 到相同的 slot,因此不一定能保证原子性。所以,在 Cluster 集群部署环境下使用 Lua 脚本时,务必确保 Lua 脚本操作的是同一个 key,以保障原子性。

为何选择用 Lua 实现原子性

在 Redis 事务中,事务队列中的所有命令需在 EXEC 命令执行时才会被执行。这就导致对于多个命令之间存在依赖关系(如后面的命令需要依赖上一个命令结果)的场景,Redis 事务显得力不从心。

Lua 脚本由于其能够顺序执行一系列命令,并且在执行过程中不会被其他客户端命令打断,更适合处理这种复杂场景,从而弥补了 Redis 事务的不足。

需要重点关注的是,ACID 中的原子性强调命令要么全部执行,要么全部不执行;而 Redis 执行 Lua 脚本的原子性是指 Lua 脚本会当作一个整体被执行且不被其他事务打断,但 Lua 脚本里面的命令并不能保证 “要么全部执行,要么全部不执行”。

通过深入了解 Redis + Lua 实现原子性的原理、Redis 的事务机制以及不同部署方式的影响,可以更加精准地运用这一技术,为分布式系统开发提供坚实的数据操作保障。

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

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

相关文章

科普:极简的AI乱战江湖

本文无图。 大模型 ‌2022年2月,‌文生图应用的鼻祖Midjourney上线。 ‌2022年8月,‌开源版的Midjourney,也就是Stable Diffusion上线。 2022年11月30日‌,OpenAI正式发布ChatGPT-3.5。 此后,不断有【大模型】面世&…

CSS- 4.5 css + div 布局 简易网易云音乐 官网布置实例

本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 HTML系列文章 已经收录在前端专栏,有需要的宝宝们可以点击前端专栏查看! 点…

【滑动窗口】LeetCode 1004题解 | 最大连续1的个数 Ⅲ

最大连续1的个数 Ⅲ 一、题目链接二、题目三、题目解析四、算法原理解法一:暴力枚举 zero计数器解法二:滑动窗口 五、编写代码六、时空复杂度 一、题目链接 最大连续1的个数 Ⅲ 二、题目 三、题目解析 注意题目中说的是最多k次,在一个数组…

PyTorch音频处理技术及应用研究:从特征提取到相似度分析

文章目录 音频处理技术及应用音频处理技术音视频摘要技术音频识别及应用 梅尔频率倒谱系数音频特征尔频率倒谱系数简介及参数提取过程音频处理快速傅里叶变换(FFT)能量谱处理离散余弦转换 练习案例:音频建模加载音频数据源波形变换的类型绘制波形频谱图波形Mu-Law 编…

鸿蒙OSUniApp 实现的语音输入与语音识别功能#三方框架 #Uniapp

UniApp 实现的语音输入与语音识别功能 最近在开发跨平台应用时,客户要求添加语音输入功能以提升用户体验。经过一番调研和实践,我成功在UniApp项目中实现了语音输入与识别功能,现将过程和方法分享出来,希望对有类似需求的开发者有…

2025年卫星遥感行业最新发展趋势深度分析

一、国内发展趋势:政策引领与技术突破双轮驱动 (一)政策体系持续完善,顶层设计深化行业发展 国家级战略与标准体系构建 中国政府将卫星遥感产业纳入“十四五”规划核心战略,明确构建“通导遥”一体化空间基础设施。20…

SIP协议栈--osip源码梳理

文章目录 osiposip主体结构体code main函数 状态机转化结构体code状态转换 sip事务结构体code osip_dialog结构体code 创建并发送200 OK响应 osip_message结构体code osip_eventcode 打印接收到的SIP消息 osip OSIP(Open Source Implementation of SIP)…

Linux之Yum源与Nginx服务篇

1.Yum源知识理论总结概括 Yum源概述 Yum 源 即软件仓库的标识,里面承载着软件包集合 Yum源组成 包含模块 【OS】、【everything】、【EPOL】、【debuginfo】、【source】、【update-source】 【os】:简称operator system 它内部包含操作系统的核心组件&#x…

从单体架构到微服务:架构演进之路

引言:当“大货车”遇上“集装箱运输” 在软件开发领域,单体架构曾像一辆载满货物的大货车,将所有功能打包在一个应用中。但随着业务复杂度飙升,这辆“大货车”逐渐陷入泥潭:启动慢如蜗牛、故障波及全局、升级如履薄冰……

AM32电调学习解读九:ESC上电启动关闭全流程波形分析

这是第九篇,前面的文章把各个模块的实现都介绍了一轮,本章是从运行的角度结合波形图,把整个流程走一遍。 先看下一运行的配置,我把一些配置关闭了,这样跑起来会好分析一些,不同配置跑起来效果会有差异。使用…

全球宠物经济新周期下的亚马逊跨境采购策略革新——宠物用品赛道成本优化三维路径

在全球"孤独经济"与"银发经济"双轮驱动下,宠物用品市场正经历结构性增长。Euromonitor数据显示,2023年全球市场规模突破1520亿美元,其中中国供应链贡献度达38%,跨境电商出口增速连续三年超25%。在亚马逊流量红…

reshape/view/permute的原理

在pytorch中,Tensor的存储是行主序的,也就是意味着最后一个维度的元素的存储时连续的,reshape和view并不改变元素存储的内存,仅仅改变访问的间隔,下面举例说明; 比如一个23的Tensor在内存中的存储是连续的&…

upload-labs靶场通关详解:第11关

一、分析源代码 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array("php","php5","php4","php3","php2","html","htm","phtml"…

L1-7 最短字母串【保姆级详细讲解】

请你设计一个程序,该程序接受起始字母和目标字母作为输入,通过在字母表中向前或向后移动来计算两个给定字母之间的最短路径。然后,程序会沿着最短路径打印出从起始字母到目标字母的所有字母。例如,如果输入“c”和“k”作为起始字…

项目QT+ffmpeg+rtsp(三)——延迟巨低的项目+双屏显示

文章目录 前言双屏显示widget.cppwidget.h前言 对于复现情况,分为两种情况 第一种,对于我而言,是直接解压后,就能直接运行了 第二种,对于师兄而言,需要你构建debug后,会产生这个文件夹,执行的时候,地址应该在这,我猜的,这里面没有dll,exe程序就找不到dll这些库,你…

ansible进阶06

复杂的循环结构 循环基础 [studentworktest myansible]$ cat users.yml --- - name: create usershosts: serveratasks:- name: create some usersuser:name: "{{item}}"password: "{{123456|password_hash(sha512)}}"state: presentloop:- zhangsan- li…

Go 模块版本管理

Go 模块版本管理指南 1、创建带注释的 Git 标签 基本命令 # 创建带注释的标签 git tag -a v1.0.0 -m "Release version 1.0.0 - initial stable release" -a:创建带注释的标签 -m:添加标签注释信息 # 推送标签到远程仓库 git push origin v…

Java—— IO流 第一期

什么是IO流 存储和读取数据的解决方案 I:input O:output 流:像水流一样传输数据 IO流的作用 用于读写数据(本地文件,网络) IO流的分类 按照流向分类 输出流:程序 --> 文件 输入流:文件 --> 程序 按照…

物联网安全技术的最新进展与挑战

随着物联网(IoT)技术的飞速发展,越来越多的设备被连接到互联网,从智能家居设备到工业控制系统,物联网正在深刻改变我们的生活和生产方式。然而,物联网的安全问题也日益凸显,成为制约其发展的关键…

【深度学习基础】损失函数与优化算法详解:从理论到实践

【深度学习基础】损失函数与优化算法详解:从理论到实践 一、引言 1. 损失函数与优化算法在深度学习中的核心作用 在深度学习中,模型训练的本质是通过不断调整参数,使模型输出尽可能接近真实值。这一过程的核心驱动力是损失函数(…