Redis中的Lua脚本(三)

Lua脚本

EVAL命令的实现

EVAL命令的执行过程可以分为以下三个步骤:

  • 1.根据客户端给定的Lua脚本,在Lua环境中定义一个Lua函数
  • 2.将客户端给定的脚本保存到lua_scripts字典,等待将来进一步使用
  • 3.执行刚刚在Lua环境中定义的函数,以此来执行客户端给定的Lua脚本
    以下命令作为示例,分别介绍EVAL命令执行的三个步骤:
127.0.0.1:6379> EVAL "return 'hello world'" 0
"hello world"

定义脚本函数

当客户端向服务器发送EVAL命令,要求执行某个Lua脚本的时候,服务器首先要做的就是在Lua环境中,为传入的脚本定义一个与这个脚本相对应的Lua函数,其中,Lua函数的名字由f_前缀加上脚本的SHA1校验和(四十个字符长)组成,而函数的体(body)则是脚本本身

使用函数来保存客户端传入的脚本有以下好处:

  • 1.执行脚本的步骤非常简单,只要调用与脚本相对应的函数即可
  • 2.通过函数的局部性来让Lua环境保持清洁,减少了垃圾回收的工作量,并且避免了使用全局变量
  • 3.如果某个脚本所对应的函数在Lua环境中被定义过至少一次,那么只要记得这个脚本的SHA1校验和,服务器就可以在不知道脚本本身的情况下,直接通过调用Lua函数来执行脚本,这时EVALSHA命令的实现原理
例子
  • 举个例子,对于命令:
EVAL "return 'hello world'" 0

来说,服务器将在Lua环境中定义以下函数:

function f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91()
return 'hello world'
end

因为客户端传入的脚本为return ‘hello world’,而这个脚本的SHA1校验和为5332031c6b470dc5a0dd9b4bf2030dea6d65de91所以函数的名字为f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91,而函数的体则为return ‘hello world’.

将脚本保存到lua_scripts字典

EVAL命令要做的第二件事是将客户端传入的脚本保存到服务器的lua_scripts字典里面。
在这里插入图片描述

例子
  • 举个例子,对于命令:
EVAL "return 'hello world'" 0

来说,服务器将在lua_scripts字典中新添加一个键值对,其中键为Lua脚本的SHA1校验和

5332031c6b470dc5a0dd9b4bf2030dea6d65de91

而值则为Lua脚本本身:

retuern 'hello world'

添加新键值对之后,lua_scripts字典如上图所示:

执行脚本函数

在为脚本定义函数,并且将脚本保存到lua_scripts字典之后,服务器还需要进行一些设置钩子、传入参数之类的准备动作,才能正式开始执行脚本。整个准备和执行脚本的过程如下:

  • 1.将EVAL命令中传入的键名(key name)参数和脚本参数分别保存到KEYS数组和ARGV数组,然后将这两个数组作为全局变量传入到Lua环境里面
  • 2.为Lua环境装载超时处理钩子(hook),这个钩子可以在脚本出现超时运行情况是,让客户端通过SCRIPT KILL命令停止脚本,或者通过SHUTDOWN命令直接关闭服务器
  • 3.执行脚本函数
  • 4.移除之前装载的超时钩子
  • 5.将执行脚本函数所得的结果保存到客户端状态的输出缓冲区里面,等待服务器将结果返回给客户端
例子
  • 举个例子。对于如下命令:
EVAL "return 'hello world'" 0

服务器将执行以下动作:
1.因为这个脚本没有给定任何键名参数或者脚本参数,所以服务器会跳过传值到KEYS数组或ARGV数组这一步
2.为Lua胡娜经装载超时处理钩子
3.在Lua环境中执行f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91函数
4.移除超时钩子
5.将执行f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91函数所得的结果"hello world"保存到客户端状态的输出缓冲区里面
6.对Lua环境执行垃圾回收操作
至此,命令:

EVAL "return 'hello world'" 0

执行算是完成了,之后服务器只要将保存在输出缓冲区里面的执行结果返回给执行EVAL命令的客户端就可以了

EVALSHA命令的实现

每个被EVAL命令成功执行过的Lua脚本,在Lua环境里面都有一个与这个脚本相对应的Lua函数,函数的名字由f_前缀加上40个字符串的SHA1校验和组成,例如f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91.只要脚本对应的函数曾经在Lua环境里面定义过,那么即使不知道脚本的内容本身,客户端也可以根据脚本的SHA1校验和来调用脚本对应的函数,从而达到执行脚本的目的,这就是EVALSHA命令的实现原理。

伪代码描述

def EVALSHA(sha1):
# 拼接出函数的名字
# 例如 f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91
func_name = "f_" + sha1# 查看这个函数在Lua环境中是否存在
if function_exists_in_lua_env(func_name):
# 如果函数存在,那么执行它
execute_lua_function(func_name)
else:
# 如果函数不存在,那么返回一个错误
send_scirpt_error("SCRIPT NOT FOUND")

例子

  • 举个例子。当服务器执行完以下EVAL命令之后:
127.0.0.1:6379> EVAL "return 'hello world'" 0
"hello world"

Lua环境里面就定义了以下函数:

function f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91()
return 'hello world'
end

当客户端执行以下EVALSHA命令时:

127.0.0.1:6379> EVALSHA 5332031c6b470dc5a0dd9b4bf2030dea6d65de91 0
"hello world"

服务器首先根据客户端输入的SHA1校验和,检查函数f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91
是否存在于Lua环境中,得到的回应时该函数确实存在,于是服务器执行Lua环境中的f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91函数,并将结果"hello world"返回给客户端

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

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

相关文章

前端如何防止接口重复提交

什么是接口重复提交? 接口重复提交指的是在网络通信中,同一个请求被客户端多次发送到服务器端的情况。这种情况可能由于多种原因导致,例如用户在等待期间多次点击提交按钮、网络超时后客户端重新发送请求、客户端发送的请求在网络传输过程中出现重复等。 接口重复提交可能…

数据应用OneID:ID-Mapping Spark GraphX实现

前言 说明 以用户实体为例,ID 类型包含 user_id 和 device_id。当然还有其他类型id。不同id可以获取到的阶段、生命周期均不相同。 device_id 生命周期通常指的是一个设备从首次被识别到不再活跃的整个时间段。 user_id是用户登录之后系统分配的唯一标识&#xff…

Typecho插件改造dplayer为<video> 标签

背景意义,插件脱离依赖,将dplayer 改成视频插入插件 由 [dplayer url"/typecho/usr/uploads/2024/03/2377219763.mp4" pic"" danmu"false" /] 成 <video src"/typecho/usr/uploads/2024/03/2377219763.mp4" controls"true…

【详细介绍下图搜索算法】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估

目录 一、说明 二、Deepset SQUAD是个啥&#xff1f; 三、问答系统&#xff08;QA系统&#xff09;&#xff0c;QA系统在各行业的应用及基本原理 3.1 医疗 3.2 金融 3.3 顾客服务 3.4 教育 3.5 制造业 3.6 法律 3.7 媒体 3.8 政府 四、在不同行业使用QA系统的基本原理 五、关于…

GPS NMEA-0183 协议

一文读懂 GPS NMEA-0183 协议 - 知乎 GPRMC Recommended Minimum Specific GPS/TRANSIT Data&#xff08;RMC&#xff09;推荐定位信息 $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>…

Java中可变个数形参的方法:初学者易懂的指南

Java中可变个数形参的方法&#xff1a;初学者易懂的指南 在Java编程中&#xff0c;可变个数形参&#xff08;Varargs&#xff0c;即variable number of arguments&#xff09;是一个非常实用的特性。它允许我们在定义方法时&#xff0c;指定一个参数可以接受任意数量的值。这对…

Java 合并两个相同的List集合多种方法解析

Java 合并两个相同的List集合多种方法解析 引言1. 使用addAll()方法方法说明 2. 使用concat()方法&#xff08;Java 8及以上版本&#xff09;3. 使用CopyOnWriteArrayList类&#xff08;线程安全场景&#xff09;4. 使用Collections.union()静态方法 引言 在Java编程中&#xf…

基于知识图谱的大学生就业能力评价和职位推荐系统——超详细要点总结(创作不易,还请点赞)

1. 职位节点&#xff08;Position&#xff09;&#xff1a; 软件工程师 数据科学家 系统架构师 网络安全专家 人工智能工程师 嵌入式系统工程师 物联网工程师 大数据工程师 前端/后端开发工程师 云计算工程师 区块链工程师 自然语言处理专家 软件测试工程师 人机交…

使用自己训练好的模型YOLOv8进行X-AnyLabeling自动标注

目录 1. 下载项目2. 创建环境3. 运行程序3.1 自行下载和添加官方模型3.2 使用自己训练好的模型标注自己的数据集 本机环境&#xff1a;win 10&#xff0c; GPU 1. 下载项目 git clone https://github.com/CVHub520/X-AnyLabeling.git2. 创建环境 仔细查看项目的README文件 …

游游的you矩阵

题目&#xff1a; 游游拿到了一个字符矩阵&#xff0c;她想知道有多少个三角形满足以下条件&#xff1a; 三角形的三个顶点分别是 y、o、u 字符。三角形为直角三角形&#xff0c;且两个直角边一个为水平、另一个为垂直。 输入描述&#xff1a; 第一行输入两个正整数n,m&#…

reduce用法

//实现一个repeat方法&#xff0c;要求如下&#xff1a; // 需要实现的函数 // const repeatFunc repeat(console.log, 4, 3000); // repeatFunc(“hello world”); //会输出4次 hello world, 每次间隔3秒 //利用map实现 function repeat(func, times, wait) { // 补全 re…

CSS简单的选择器

标签选择器 与网页元素同名的选择器。常用于与设置网页默认效果&#xff0c;或者统一常用元素的基本样式。 p{font-size&#xff1a;10px&#xff1b; }类选择器 可以为网页对象定义不同的样式&#xff0c;实现不同元素拥有相同的样式&#xff0c;相同元素的不同对象拥有不同…

Root mapping definition has unsupported parameters: [all : {analyzer=ik_max_wor

你们好&#xff0c;我是金金金。 场景 我正在使用Springboot整合elasticsearch&#xff0c;在创建索引(分词器) 运行报错&#xff0c;如下 排查 排查之前我先贴一下代码 import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; // 注意这个包SpringBootTe…

文字转语音工具:GPT-SoVITS

诸神缄默不语-个人CSDN博文目录 OpenAI官方的TTS模型我在这篇博文中给出了使用教程&#xff1a;ChatGPT 3.5 API的调用不全指南&#xff08;持续更新ing…&#xff09; - 知乎 但是OpenAI的TTS对中文支持不好&#xff0c;有一种老外说中文的美&#xff0c;所以本文介绍另一个…

windows@允许挂载http链接@挂载局域网http链接

文章目录 资源管理器挂载网络驱动器&#x1f47a;允许http链接映射为磁盘驱动器&#x1f60a;可选更改:文件大小限制 刷新使配置生效重启webclient服务 基本操作执行映射取消映射 资源管理器挂载网络驱动器&#x1f47a; 对于共享文件夹(smb)协议(\\server\sharefolder)类型的…

自己的事情自己做:使用 Python Turtle 绘制 Python Logo

以下代码中&#xff0c;将向你展示一个有趣的程序&#xff0c;如何使用 Python Turtle 中绘制 Python Logo。Python 翻译成汉语是蟒蛇的意思&#xff0c;Python 的 Logo 也是两条缠绕在一起的蟒蛇。 import turtlepen turtle.Turtle() turtle.bgcolor("black") pe…

ins视频批量下载,instagram批量爬取视频信息【爬虫实战课1】

简介 Instagram 是目前最热门的社交媒体平台之一,拥有大量优质的视频内容。但是要逐一下载这些视频往往非常耗时。在这篇文章中,我们将介绍如何使用 Python 编写一个脚本,来实现 Instagram 视频的批量下载和信息爬取。 我们使用selenium获取目标用户的 HTML 源代码,并将其保存…

Python路面车道线识别偏离预警

程序示例精选 Python路面车道线识别偏离预警 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《Python路面车道线识别偏离预警》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易…

AOP动态修改注解值及异步子线程请求头丢失问题

1、动态注入参数&#xff1a;通过AOP注解占位符&#xff0c;匹配目标方法参数&#xff0c;可用于日志记录等场景 AOP 注解动态注入参数 - 简书 2、spel表达式匹配目标方法的参数进行动态入参 自定义注解动态入参绑定_注解参数值动态注入-CSDN博客 3、Java没有提供直接设置线…