当前位置: 首页 > 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 …...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

dify打造数据可视化图表

一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...