Lua脚本使用手册(Redis篇)

Lua脚本

**简介:**Lua是一种功能强大的,高效,轻量级,可嵌入的脚本语言。它是动态类型语言,通过使用基于寄存器的虚拟机解释字节码运行,并具有增量垃圾收集的自动内存管理,是配置,脚本和快速原型设计的最佳选择

Redis中使用lua脚本的原因
  • 减少网络延迟:Lua脚本将多个Redis命令组合成一个脚本,减少了客户端与服务器之间的网络交互。同时,Redis服务器还提供了EVALSHA命令,可以将脚本的SHA1值缓存在服务器中,下次再执行同样的脚本时,只需传递SHA1值即可,减少了网络传输时间。

  • 原子操作:Lua脚本可以保证多个Redis命令的原子性,避免了并发问题

Redis怎么执行Lua脚本
1、lua函数

Lua脚本使用两个不同的Lua函数来调用任意的Redis命令

redis.call()
redis.pcall()

当redis命令执行结果返回错误时

  • call() 将返回给调用者一个错误,

  • pcall() 将捕获的错误以Lua表的形式返回

127.0.0.1:6379> EVAL "return redis.call('xxxx')" 0
(error) ERR Error running script (call to f_1e6efd00ab50dd564a9f13e5775e27b966c2141e): @user_script:1: @user_script: 1: Unknown Redis command called from Lua script127.0.0.1:6379> EVAL "return redis.pcall('xxxx')" 0
(error) @user_script: 1: Unknown Redis command called from Lua script
2、脚本执行

Redis Lua脚本可以通过 EVAL 命令或者 EVALSHA 命令执行

EVAL script numkeys [key [key ...]] [arg [arg ...]]
EVALSHA sha1 numkeys [key [key ...]] [arg [arg ...]]
  • numkeys: the number of input key name arguments,keyname的数量
  • key : the name of key,多个keyname空格隔开。在Lua 脚本中通过 KEYS[INDEX]来获取对应的name,其中1 <= INDEX <= numkeys
  • arg : all the keys accessed by the script,多个key空格隔开,在Lua脚本中通过ARGV[INDEX]来获取对应的key,其中1 <= INDEX <= numkeys

EVAL EVALSHA 命令的区别

  • EVAL 命令要求你在每次执行脚本的时候都发送一次脚本主体(script body)。Redis 有一个内部的脚本缓存机制,因此它不会每次都重新编译脚本
  • EVALSHA 命令, Evaluate a script from the server’s cache by its SHA1 digest. 。在执行EVALSHA的时候根据

具体的使用方法如下

使用 EVAL 命令

127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 username zhangsanOK
127.0.0.1:6379> EVAL "return redis.call('GET', KEYS[1])" 1 username
"zhangsan"

在较新的版本中,lua脚本又新增了许多命令,比如下面的 EVAL_RO,是 EVAL 的一个变种,表示只读,修改数据的命令是不能被执行的

在这里插入图片描述

SCRIPT LOADEVALSHA 命令

使用 SCRIPT LOAD 命令加载lua脚本到服务器脚本缓存中,以达到重复使用,避免多次加载浪费带宽,加载但不会执行这个lua脚本,并返回一个sha校验值。需要配合EVALSHA命令来执行缓存后的脚本

127.0.0.1:6379> SCRIPT LOAD "return 'hello'"
"1b936e3fe509bcbc9cd0664897bbe8fd0cac101b"
127.0.0.1:6379> EVALSHA 1b936e3fe509bcbc9cd0664897bbe8fd0cac101b 0
"hello"

不会经常变动的脚本推荐使用 EVALSHA

官方文档:https://redis.io/docs/latest/commands/?group=scripting

应用场景
  • 事务操作:Lua脚本可以保证一组Redis命令的原子性
springboot实战
实现分布式锁
public String tryLock() {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptSource(new ResourceScriptSource(new ClassPathResource("tryLock.lua")));script.setResultType(Long.class);Long state = stringRedisTemplate.execute(script, Lists.newArrayList("lock-good"), "uuid");if (state == 1){log.info("获取锁成功");}else {log.info("获取锁失败");}return "";
}public String releaseLock() {DefaultRedisScript<Boolean> script = new DefaultRedisScript<>();script.setScriptSource(new ResourceScriptSource(new ClassPathResource("releaseLock.lua")));Boolean releaseLock = stringRedisTemplate.execute(script, Lists.newArrayList("lock-good"));if (releaseLock){log.info("释放锁成功");}else {log.info("释放锁失败");}return "";
}

lua脚本

tryLock.lua

local key = KEYS[1];
local value = ARGV[1];
local expireTime = ARGV[2];
if redis.call('SETNX', key, value) == 1 thenreturn redis.call('PEXPIRE', key, expireTime);
elsereturn 0;
end

releaseLock.lua

local key = KEYS[1];
local value = ARGV[1];
if redis.call('GET', key) == value thenredis.call('DEL', key);return true;
elsereturn false;
end
数据更新

update.lua

local key = KEYS[1];
local value = ARGV[1];
local pexpire = ARGV[1];
if redis.call('GET',key) == value thenredis.call('SET', key, value);redis.call('PEXPIRE', key, pexpire)return 1;
elsereturn 0;
end

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

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

相关文章

26、Lua 学习笔记之四(Lua中的基本函数库)

Lua中的基本函数库 assert(v[,mess age])collectgarbage (opt [, arg])dofile (filename)error (message [, level])_G全局环境表(全局变量)getfenv(f)getmetatable(object)ipairs (t)load (func [, chunkname])loadfile ([filename])loadstring (string [, chunkname])next (t…

electron自动更新版本,复制可用

1、安装electron-updater要保证这3个安装在package.json - devDependencies里面&#xff0c;否则打包会缺少模块 2、其他报错有可能 electron版本和electron-updater 版本不兼容&#xff0c;兼容情况查询官网 3、setFeedURL&#xff08;&#xff09; 服务器地址目录 例如&#…

MySQL详细使用

1.安装 官网下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions) 2.配置 添加环境变量 验证是否添加成功 cmd管理员身份打开&#xff0c;输入mysql&#xff08;如下为成功&#xff09; 初始化MySQL 以管理员身份运行cmd 输入 mysqld --ini…

React搭建一个文章后台管理系统

1、项目准备 本篇文章讲解的是一个简单的文章后台管理系统&#xff0c;系统的功能很简单&#xff0c;如下&#xff1a;登录、退出&#xff1b;首页&#xff1b;内容(文章)管理&#xff1a;文章列表、发布文章、修改文章。 1&#xff09;React官方脚手架&#xff1a;create-rea…

安装IntelliJ IDEA插件教程

安装IntelliJ IDEA插件&#xff1a;一份详细指南 在提升IntelliJ IDEA开发效率的过程中&#xff0c;插件扮演着不可或缺的角色。它们为IDE提供了额外的功能和工具&#xff0c;以满足开发者在特定编程语言、框架、测试、版本控制等方面的个性化需求。本文将为您详细阐述如何在I…

【已开源】​基于stm32f103的爬墙小车

​基于stm32f103的遥控器无线控制爬墙小车&#xff0c;实现功能为可平衡在竖直墙面上&#xff0c;并进行移动和转向&#xff0c;具有超声波防撞功能。 直接上&#xff1a; 演示视频如&#xff1a;哔哩哔哩】 https://b23.tv/BzVTymO 项目说明&#xff1a; 在这个项目中&…

数模 线性规划模型理论与实践

线性规划模型理论与实践 1.1 线性规划问题 在人们的生产实践中&#xff0c;经常会遇到如何利用现有资源来安排生产&#xff0c;以取得最大经济效益的问题。此类问题构成了运筹学的一个重要分支一数学规划&#xff0c;而线性规划(Linear Programming 简记LP)则是数学规划的一个…

架构师系列-搜索引擎ElasticSearch(五)- 索引设计

索引创建后&#xff0c;要非常谨慎&#xff0c;创建不好后面会出现各种问题。 索引设计的重要性 索引创建后&#xff0c;索引分片只能通过_split和_shrink 接口对其进行成倍的增加和缩减。 ES的数据是通过_routing分配到各个分片上的&#xff0c;所以本质上不推荐区改变索引的…

ubuntu git相关操作

1 安装git sudo apt install git git --version git version 2.25.1 2 解决git超时 2.1 扩大post的buffer git config --global http.postBuffer 524288000 git config --global http.postBuffer 157286400 2.2 换回HTTP1上传。上传之后再切换回HTTP2 …

AI克隆语音(基于GPT-SoVITS)

概述 使用GPT-SoVITS训练声音模型&#xff0c;实现文本转语音功能。可以模拟出语气&#xff0c;语速。如果数据质量足够高&#xff0c;可以达到非常相似的结果。相比于So-VITS-SVC需要的显卡配置更低&#xff0c;数据集更小&#xff08;我的笔记本NVIDIA GeForce RTX 4050 Lap…

智能水务系统:构建高效节水的城市水网

随着城市化进程的加速和人民生活水平的提高&#xff0c;对水务管理的需求也越来越高。传统的水务管理方式已经无法满足现代社会的需求&#xff0c;而智能水务系统的出现为水务管理带来了新的变革。本文将从项目背景、需求分析、建设目标、建设内容、技术方案、安全设计等方面&a…

网络篇06 | 应用层 自定义协议

网络篇06 | 应用层 自定义协议 01 固定协议设计&#xff08;简化版&#xff09;1&#xff09;总体设计2&#xff09;值设计 02 可变协议设计&#xff08;进阶版&#xff09;1&#xff09;固定头&#xff08;Fixed Header&#xff09;2&#xff09;可变头&#xff08;Variable H…

UBuntu18.04通过ODBC连接MySQL远程数据库

今天在做一个Qt视频播放器的小项目然后想要在ubuntu18.04运行这个项目&#xff0c;需要在Qt中连接远程的MySQL数据库&#xff0c;所以用到了ODBC。我在连接时遇到了一些问题&#xff0c;加之网上的教程各说纷纭&#xff0c;所以我花了很多时间去解决&#xff0c;所以决定做做笔…

数据资产与数据要素的重要性及数据资产入表的实践指南

## 引言在当今快速发展的数字化时代&#xff0c;数据资产已经成为企业最宝贵的资源之一。数据资产不仅对企业的运营决策有着至关重要的影响&#xff0c;而且在企业的财务健康和市场竞争力方面扮演着核心角色。数据要素&#xff0c;作为构成数据资产的基本单元&#xff0c;其管理…

【CSS】CSS水平居中方案

CSS水平居中方案 1. 行内元素水平居中 设置父元素的text-align:center .box {width: 300px;height: 300px;margin: 100px auto;text-align: center;background-color: pink; }2. 块级元素水平居中 当块级元素设置了明确的宽度数值时&#xff0c;可以使用margin: 0 auto 3.…

【opencv】示例-stiching_detailed.cpp 使用OpenCV进行图像拼接的整体流程

#include <iostream> // 引入输入输出流库 #include <fstream> // 引入文件流库&#xff0c;用于文件输入输出 #include <string> // 引入字符串库 #include "opencv2/opencv_modules.hpp" // 引入OpenCV模块 #include <opencv2/core/utility.h…

2023年看雪安全技术峰会(公开)PPT合集(11份)

2023年看雪安全技术峰会&#xff08;公开&#xff09;PPT合集&#xff0c;共11份&#xff0c;供大家学习参阅。 1、MaginotDNS攻击&#xff1a;绕过DNS 缓存防御的马奇诺防线 2、从形式逻辑计算到神经计算&#xff1a;针对LLM角色扮演攻击的威胁分析以及防御实践 3、TheDog、0…

2024软件工程第一次作业

communication tasks Set a project (can use the project I give in the class in the file), then try to develop a set of actions for the communication activity. Select one action and define a task set for it. 1.设置一个项目&#xff08;可以使用我上课在文件中给…

python调用Microsoft Word把文件夹下所有docx或doc批量转化为PDF

python调用Microsoft Word把文件夹下所有docx或doc批量转化为PDF 首先&#xff0c;确保你的系统上安装了Microsoft Word。然后&#xff0c;你需要安装comtypes库&#xff0c;如果你还没有安装&#xff0c;可以通过以下命令进行安装&#xff1a; pip install comtypes以下是一个…

Mac 软件清单

~自留备用~ Macbook用了几年之后, 512G的内置硬盘有些紧张了, 这几天总是提示空间不足, 就重装了下系统, 重装之后竟然不记得有些软件的名字和下载链接, 特此记录 Office 办公套件 直接从微软官网下载Office 安装包https://officecdnmac.microsoft.com/pr/C1297A47-86C4-4C1F…