【Redis】Redis 的学习教程(十二)之在 Redis使用 lua 脚本

news/2025/2/21 15:48:18/

lua 菜鸟教程:https://www.runoob.com/lua/lua-tutorial.html

在 Redis 使用 lua 脚本的好处:

  1. 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延及开销
  2. 原子性操作。Redis会将整个脚本作为一个整体执行,中间不会被其他请求插入。因此在脚本运行过程中无需担心会出现竞态条件,无需使用事务
  3. 复用。客户端发送的脚本会永久存在redis中,这样其他客户端可以复用这一脚本,而不需要使用代码完成相同的逻辑

1. 常用命令

  • EVAL:将脚本 script 添加到脚本缓存中,并且立即执行这个脚本
    • 语法:EVAL script numkeys key [key …] arg [arg …]
    • 参数含义:
      • script:是 Lua5.1 脚本程序。此Lua脚本不需要也不应该定义函数,它运行在 Redis 服务器中
      • numkeys:键名参数的个数。即:key [key …] 中 key 的个数。如没有 key,则为 0
      • key[]:键名参数,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 lua 中通过全局变量 KEYS 数组。在 lua 脚本中通过 KEYS[1],KEYS[2] 获取
      • arg [arg …] :不是键名参数的附加参数,可以在 lua 中通过全局变量 ARGV 数组访问。在 lua 脚本中通过 ARGV[1],ARGV[2] 获取
    • 案例
      1. 调用 set 方法:EVAL "return redis.call('set', 'name', 'bob')" 0
      2. 调用 set 方法(使用参数):EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 name jack
  • EVALSHA:根据给定的 sha1 校验码,执行缓存在服务器中的脚本。将脚本缓存到服务器的操作可以通过 SCRIPT LOAD 命令进行。这个命令的其他地方,比如参数的传入方式,都和 EVAL 命令一样
    • 语法:EVALSHA sha1 numkeys key [key ...] arg [arg ...]
  • SCRIPT LOAD:将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。 在脚本被加入到缓存之后,通过 EVALSHA 命令,可以使用脚本的 SHA1 校验和来调用这个脚本。
    脚本可以在缓存中保留无限长的时间,直到执行 SCRIPT FLUSH 为止
    • 语法:SCRIPT LOAD script
    • 返回:脚本的 SHA1 校验和
  • SCRIPT EXISTS:校验指定的脚本是否已经被保存在缓存当中
    • 语法:SCRIPT EXISTS sha1 [sha1 ...]
  • SCRIPT FLUSH:清除 Redis 服务端所有 lua 脚本缓存
  • SCRIPT KILL用于杀死当前正在运行的 lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限循环的脚本

案例:

redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'"    # 载入一个脚本
"232fd51614574cf0867b83d384a5e898cfd24e5a"redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 1redis 127.0.0.1:6379> SCRIPT FLUSH     # 清空缓存
OKredis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 0

2. 具体业务使用案例

基于 Redis 的分布式锁

释放锁的流程:

  1. 获取锁中的线程标识
  2. 判断是否与指定的标识(当前线程标识)一致
  3. 如果一致,则删除;否则,什么都不做

unlock.lua 如下:resources/unlock.lua

-- 比较线程标示与锁中的标示是否一致
if(redis.call('get', KEYS[1]) ==  ARGV[1]) then-- 释放锁 del keyreturn redis.call('del', KEYS[1])
end
return 0

在 Java 中调用:

// 初始化 lua 脚本文件
private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
static {UNLOCK_SCRIPT = new DefaultRedisScript<>();//lua脚本位置UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));//返回值类型UNLOCK_SCRIPT.setResultType(Long.class);
}// 使用 lua 脚本释放锁
public void unlock(String lockKey,String lockValue){// 调用lua脚本redisTemplate.execute(UNLOCK_SCRIPT,Collections.singletonList(lockKey),lockValue);
}

http://www.ppmy.cn/news/1130355.html

相关文章

AD20软件学习

一.建立文件夹以及汉化操作 1.创建工程 菜单栏- > File -> New -> Project 2.创建原理图 菜单栏- > File -> New -> Schematic 记得保存&#xff01;&#xff01;&#xff01; 3.创建PCB 菜单栏- > File -> New -> PCB 依次为综合库&#xff0c;原…

(自学)黑客————网络安全技术

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…

【数据仓库设计基础(四)】数据仓库实施步骤

文章目录 1&#xff0e;定义范围2&#xff0e;确定需求3&#xff0e;逻辑设计1&#xff09;建立需要的数据列表2&#xff09;识别数据源3&#xff09;制作实体关系图 4&#xff0e;物理设计1&#xff09;性能优化2&#xff09;数仓的拓展性 5&#xff0e;装载数据6&#xff0e;…

CCF CSP认证 历年题题目自练Day16

CCF CSP认证 历年题题目自练Day16 题目一 试题编号&#xff1a; 201712-1 试题名称&#xff1a; 最小差值 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   给定n个数&#xff0c;请找出其中相差&#xff08;差的绝对值&#xf…

零代码编程:用ChatGPT批量自动下载archive.org上的音频书

http://archive.org 是一个神奇的网站&#xff0c;可以下载各种古旧的软件、书籍、音频、视频&#xff0c;还可以搜索各个网站的历史网页。 比如说&#xff0c;一些儿童故事音频就可以在http://archive.org下载到&#xff0c;可以用来做英语听力启蒙用。 举个例子&#xff0c…

[杂谈]-ESP32中的无线通信协议

ESP32中的无线通信协议 文章目录 ESP32中的无线通信协议1、ESP32 无线通信协议简介2、Bluetooth Low Energy (BLE)3、**Bluetooth Classic**4、**ESP-NOW**5、Wi-Fi&#xff08;客户端-服务器通信协议&#xff09;6、MQTT7、**LoRa**8、**GSM/GPRS/LTE**9、总结 ESP32是一个基于…

ChatGPT,AIGC 助力人力资源管理对身份证号处理

HR&#xff0c;行政&#xff0c;文员办公对于员工信息管理中有一项目非常重要的操作&#xff0c;便是从身份证号中提取相关信息如下&#xff1a; 可以用ChatGPT完成三个字段的提取与计算。 我们先让ChatGPT描述一下身份证号每一位都代表什么意思。 接下来从身份证号中提取出生…

运行软件mfc100u.dll缺失是怎么办?mfc100u.dll丢失解决方法分享

Mfc100u.dll 丢失的问题可能困扰着许多使用计算机的用户。Mfc100u.dll 是一个重要的动态链接库文件&#xff0c;它包含了许多功能模块&#xff0c;如字符串处理、数学计算、文件操作等。当 Mfc100u.dll 文件丢失或损坏时&#xff0c;可能会导致许多应用程序无法正常运行&#x…