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,一经查实,立即删除!

相关文章

MySQL详细使用

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

【已开源】​基于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;所以本质上不推荐区改变索引的…

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;其管理…

【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…

Mac 软件清单

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

Kafka 简单介绍

目录 一 消息队列&#xff08;MQ&#xff09; 1&#xff0c;为什么需要消息队列&#xff08;MQ 2&#xff0c;常见的 MQ 中间件 3&#xff0c;MQ 传统应用场景之异步处理 4&#xff0c;使用消息队列的好处 5&#xff0c;消息队列的两种模式 5.1点对点模式&#xf…

车载电子电器架构 —— 平行开发策略

车载电子电器架构 —— 平行开发策略 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己…

Jmeter配置服务器监控插件

1.安装插件管理器 插件官网地址&#xff1a;JMeter Plugins :: JMeter-Plugins.org 点击 Plugins Manager,如上图所示&#xff0c; &#xff0c;点击jar file下载“plugins-manager.jar”&#xff0c;下载后放到“jmeter\lib\ext”目录下&#xff0c;重启jmeter。 2.安装资源…

网络篇04 | 应用层 mqtt(物联网)

网络篇04 | 应用层 mqtt&#xff08;物联网&#xff09; 1. MQTT协议介绍1.1 MQTT简介1.2 MQTT协议设计规范1.3 MQTT协议主要特性 2 MQTT协议原理2.1 MQTT协议实现方式2.2 发布/订阅、主题、会话2.3 MQTT协议中的方法 3. MQTT协议数据包结构3.1 固定头&#xff08;Fixed header…

论文笔记:The Expressive Power of Transformers with Chain of Thought

ICLR 2024 reviewer 评分 6888【但是chair 很不喜欢】 1 intro 之前的研究表明&#xff0c;即使是具有理想参数的标准Transformer&#xff0c;也无法完美解决许多大规模的顺序推理问题&#xff0c;如模拟有限状态机、判断图中的节点是否相连&#xff0c;或解决矩阵等式问题 这…

系统架构最佳实践 -- 统一身份认证系统

目录 1.系统架构设计&#xff1a; 2.用户认证与授权&#xff1a; 3.用户身份管理&#xff1a; 4.安全性保障&#xff1a; 5.日志记录与审计&#xff1a; 6.高可用性与容错性&#xff1a; 7.用户体验优化&#xff1a; 随着互联网的快速发展和应用的普及&#xff0c;人们在…

Linux操作系统中关于用户管理的操作

创建新用户 useradd 【选项】 用户名 在/etc/passwd中以追加的方式在passwd的最后一行添加用户信息。 可以使用命令tail -n 1/etc/passwd查看文件的最后一行内容。 ls /home/首先/home/这是普通用户的家目录&#xff0c; 在/home/下会有一个跟用户名同名的家目录&#xf…

《经典论文阅读2》基于随机游走的节点表示学习—Deepwalk算法

word2vec使用语言天生具备序列这一特性训练得到词语的向量表示。而在图结构上&#xff0c;则存在无法序列的难题&#xff0c;因为图结构它不具备序列特性&#xff0c;就无法得到图节点的表示。deepwalk 的作者提出&#xff1a;可以使用在图上随机游走的方式得到一串序列&#x…