当前位置: 首页 > news >正文

Redis系列——Lua脚本和redis事务的应用

介绍

Lua脚本

背景

Redis是一种抽象数据类型的特定领域语言,由各种命令组成。大多数命令专门用于操作不通的数据类型。每次发送命令均需要执行至此网络请求。所以Redis提供了一个编程接口,支持服务器执行用户自定义的任意脚本。有助于减少网络流量,并提高整体性能。在脚本中可以执行多个命令,封装一定的业务逻辑。

运行脚本

首先,自Redis2.6.0以来,EVAL命令支持运行服务器端脚本。Eval脚本提供了一种快速而直接的方法,让Redis临时运行脚本。这意味着脚本必须在应用程序中维护,以便于随时加载。随着应用程序的发展,这种方法后续更难开发和维护。

其次,在v7.0中添加的Redis函数本质上是作为一类数据库元素的脚本。因此,函数将脚本与应用程序逻辑分离,并支持脚本的独立开发、测试和部署。若要使用函数,需要先加载它们,然后才能供所有连接的客户端使用。在这种情况下,将函数加载到数据库将成为一项管理部署任务(例如加载Redis模块),这会将脚本与应用程序分开。

在运行脚本或函数时,Redis保证其原子执行。脚本的执行会在整个时间内阻止所有服务器活动,类似于事务的语义。这些语义意味着脚本的所有效果要么尚未发生,要么已经发生。已执行脚本的阻塞语义始终适用于所有连接的客户端。

所以必须要注意的是执行的脚本不是是一个慢脚本。如果执行过慢,会阻塞所有的客户端请求。

用法

使用 EVAL 命令开始使用 Redis 编写脚本。

> EVAL "return 'Hello, scripting!'" 0
"Hello, scripting!"

在此示例中,EVAL采用两个参数。第一个参数是一个字符串,由脚本的Lua源代码组成。该脚本不需要包含Lua函数的任何定义。它只是一个将在Redis引擎上下文中运行的Lua程序。

第二个参数是脚本正文后面的参数数,从第三个参数开始,表示Redis键名。在此示例中,我们使用值0,因为我们没有为脚本提供任何参数,无论是否为键的名称。

执行上下文可以通过KEYS和ARGV全局运行时变量使参数可供脚本使用。KEYS表预先填充了在执行脚本之前提供给脚本的所有键名参数,而ARGV表具有类似的用途,但用于常规参数。

redis> EVAL "return { KEYS[1], KEYS[2], ARGV[1], ARGV[2], ARGV[3] }" 2 key1 key2 arg1 arg2 arg3
1) "key1"
2) "key2"
3) "arg1"
4) "arg2"
5) "arg3"

Redis事务

原理

Redis事务允许执行一组命令在一个步骤中,它们以MULTIEXECDISCARD和WATCH命令为中心。Redis事务提供两项重要保证:

  • 事务中的所有命令都序列化并执行顺序。另一个客户端发送的请求永远不会在执行Redis事务的过程中提供服务。这保证了命令作为单个命令执行隔离操作。

  • EXEC命令触发事务中所有命令的执行,因此如果客户端在事务,在调用EXEC命令之前,不执行任何操作,如果调用EXEC命令,则所有执行操作。使用仅追加文件时,Redis确保使用单个write(2) syscall将事务写入磁盘。但是,如果Redis服务器崩溃或被系统管理员杀死在某种程度上,可能只有部分操作已注册。Redis将在重新启动时检测到此情况,并退出并显示错误。使用redis-check-aof该工具可以修复仅附加将删除部分事务的文件,以便服务器可以重新启动。

从版本2.2开始,Redis以乐观锁定的形式,以一种非常相似的方式检查和设置(CAS)操作。

用法

使用MULTI命令输入Redis事务。命令总是回复OK。此时,用户可以发出多个命令。Redis不会执行这些命令,而是会排队他们。调用EXEC后,将执行所有命令。

相反,调用DISCARD将刷新事务队列并退出交易。

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

从上面的会话中可以清楚地看出,EXEC返回一个回复数组,其中每个元素都是单个命令的回复在事务中,命令的发出顺序相同。

事务中命令错误

从Redis2.6.5开始,服务器会在命令累积过程中检测到错误。然后,它将拒绝执行事务,在EXEC期间返回错误,从而丢弃事务。

相反,EXEC之后发生的错误不会以特殊方式处理:即使某些命令在事务期间失败,所有其他命令也会被执行。

回滚?

Redis事务不支持回滚。

Redis Lua脚本和事务使用场景

对于redis中的事务类操作,还需要考虑其他事项,即redis脚本,它们是事务性的。可以用 Redis 事务 做的所有事情,也可以用脚本来做,通常脚本会更简单、更快捷。

缺点

Lua脚本缺点

  1. 所有客户端必须要维护所有的脚本副本。
  2. EVAL是一种反模式。它们往往在短期内看起来有效,但长期来看会增加技术债务、降低代码质量和团队效率。
  3. 脚本之间无法互相调用;
  4. 无法直接支持redis cluster模式,需要运算key对应的哈希槽。

Redis事务缺点

  1. Redis事务不支持归滚;
  2. Redis事务每条命令都与redis服务器进行一次网络交互;

相关文章:

Redis系列——Lua脚本和redis事务的应用

介绍 Lua脚本 背景 Redis是一种抽象数据类型的特定领域语言,由各种命令组成。大多数命令专门用于操作不通的数据类型。每次发送命令均需要执行至此网络请求。所以Redis提供了一个编程接口,支持服务器执行用户自定义的任意脚本。有助于减少网络流量&am…...

rtt设备驱动框架面向对象学习-i2c总线

本来想着i2c和spi是一样的,标题都想抄袭成《rtt设备驱动框架学习-i2c总线和设备》,然后看过源码发现,i2c没有分开总线和设备,我想着正常它和spi一样有总线和设备,设备存在竞争。估计是因为i2c设备可以通过i2c地址区分&…...

Golang 基础 Go Modules包管理

Golang 基础 Go Modules包管理 在 Go 项目开发中,依赖包管理是一个非常重要的内容,依赖包处理不好,就会导致编译失败,本文将系统介绍下 Go 的依赖包管理工具。 我会首先介绍下 Go 依赖包管理工具的历史,并详细介绍下…...

图数据库 之 Neo4j - 背景介绍(1)

引言 Neo4j是一种高性能的图数据库,它专门设计用于存储、管理和查询大规模的图数据。与传统的关系型数据库不同,Neo4j以图的形式存储数据,其中节点表示实体,边表示实体之间的关系。这种图数据模型非常适合表示复杂的关系和连接。…...

JAVA中的单例模式->饿汉式

一、步骤 1.构造器私有化>防止直接new // 步骤一、构造器私有化>防止直接new private GirlFriend(String name){System.out.println("构造器被调用");this.name name; } 2.类的内部创建对象 // 步骤二、类的内部创建对象(该对象是static&#x…...

从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器

导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客 上一章我们完成了netty服务启动的相关抽象(https://blog.csdn.net/money9sun/article/details/136025471),这一章我们再新增一个全…...

git 合并多条提交记录

我要合并多条提交记录(合并前7条为一条),实现如下效果: 使用git rebase // 查看前10个commit git log -10 // 将7个commit压缩成一个commit;注意:vim编辑器 git rebase -i HEAD~4 // add已经跟踪的文件 g…...

C++多线程:this_thread 命名空间

std::this_thread 是 C 标准库中提供的一个命名空间,它包含了与当前线程相关的功能。这个命名空间提供了许多与线程操作相关的工具,使得在多线程环境中更容易进行编程。 源码类似于如下: namespace std{namespace this_thread{//...........…...

《山雨欲来-知道创宇 2023 年度 APT 威胁分析总结报告》

下载链接: https://pan.baidu.com/s/1eaIOyTk12d9mcuqDGzMYYQ?pwdzdcy 提取码: zdcy...

Qt信号和槽机制(什么是信号和槽,connect函数的形式,按钮的常用信号,QWidget的常用槽,自定义槽函数案例 点击按钮,输出文本)

一.什么是信号和槽 信号槽式Qt中的一个很重要的机制。信号槽实际上是观察者模式,当发生了感兴趣的事件,某一个操作就会被自动触发。当某个事件发生之后,比如按钮检测到自己被点击了一下,它就会发出一个信号。这种发出类似广播。如果有对象对…...

彻底弄懂mktemp命令的作用

mktemp 是一个在 Unix 和类 Unix 系统中用于创建临时文件或目录的命令行工具。它属于 GNU coreutils 套件的一部分。mktemp 的主要优点是它能够生成一个唯一的文件名,这有助于避免文件名冲突,并且可以安全地创建临时文件,因为这些文件通常只有…...

政安晨:示例演绎TensorFlow的官方指南(二){Estimator}

咱们接着演绎TensorFlow官方指南,我的这个系列的上一篇文章为: 政安晨:示例演绎TensorFlow的官方指南(一){基础知识}https://blog.csdn.net/snowdenkeke/article/details/136067030为什么要演绎官方指南,我…...

vue3:24—组件通信方式

目录 1、props 2、自定义事件 (emit) 3、mitt(任意组件的通讯) 4、v-model【封装ui组件库用的多,平时用的少。和vue2有点不同】 5、$attrs 6、$refs和$parent 7、provide和inject 8、pinia(即vue2中…...

WebGL+Three.js入门与实战——绘制水平移动的点、通过鼠标控制绘制(点击绘制、移动绘制、模拟画笔)

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...

大数据环境搭建(一)-Hive

1 hive介绍 由Facebook开源的,用于解决海量结构化日志的数据统计的项目 本质上是将HQL转化为MapReduce、Tez、Spark等程序 Hive表的数据是HDFS上的目录和文件 Hive元数据 metastore,包含Hive表的数据库、表名、列、分区、表类型、表所在目录等。 根据Hive部署模…...

mac电脑上使用android studio创建flutter项目

mac电脑环境配置可以看这篇文章:https://xiaoshen.blog.csdn.net/article/details/136068650 配置玩环境之后,开始创建第一个flutter项目:点击new flutter project或者new project都可以 然后选择flutter: 并将sdk配置为解压后的…...

Excel——分类汇总

1.一级分类汇总 Q:请根据各销售地区统计销售额总数。 第一步:排序,我们需要根据销售地区汇总数据,我们就要对【销售地区】的内容进行排序。点击【销售地区】列中任意一个单元格,选择【数据】——【排序】&#xff0c…...

Backtrader 文档学习- Observers - Reference

Backtrader 文档学习- Observers - Reference 1.Benchmark class backtrader.observers.Benchmark() 观察器存储策略的回报和参考资产的回报,参考资产是传递给系统的数据之一。 参数: timeframe (default: None) ,如果None,则将…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Radio组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Radio组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Radio组件 单选框,提供相应的用户交互选择项。 子组件 无。 接口 …...

【go】结构体切片去重

场景 自定义结构体切片,去除切片中的重复元素(所有值完全相同) 代码 // 自定义struct去重 type AssetAppIntranets struct {ID string json:"id,omitempty"AppID string json:"app_id,omitempty"IP …...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

条件运算符

C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...