Lua脚本使用手册(Redis篇)

news2024/11/17 19:35:50

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 script

127.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 zhangsan
 OK
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 then
    return redis.call('PEXPIRE', key, expireTime);
else
    return 0;
end

releaseLock.lua

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

update.lua

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

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

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

相关文章

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

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

【攻防世界】bug

垂直越权IP绕过文件上传 文件上传绕过&#xff1a; 1. mime检测 2. 大小写绕过 3. 等价替换&#xff08;php5&#xff0c;php3&#xff09; 4. 利用JavaScript执行php代码&#xff08;正常的php代码会被检测到&#xff0c;所以就用JavaScript来执行&#xff09; <script lan…

终端工具命令行颜色配置(解决终端工具连上服务器之后,无颜色问题)

本期主题&#xff1a; 讲解使用mobaxterm等终端工具连上服务器&#xff0c;但是命令行没有颜色的问题 目录 1. 问题描述2. 原因解释3.测试 1. 问题描述 使用终端工具&#xff08;Mobaxterm等&#xff09;连上服务器之后&#xff0c;发现终端工具没有颜色&#xff0c;如下图&am…

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

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

深度学习学习日记4.14 数据增强 Unet网络部分

数据增强 transforms.Compose([&#xff1a;这表示创建一个转换组合&#xff0c;将多个数据转换操作串联在一起 transforms.RandomHorizontalFlip()&#xff1a;这个操作是随机水平翻转图像&#xff0c;以增加数据的多样性。它以一定的概率随机地水平翻转输入的图像。 transfo…

系统架构最佳实践 -- 金融企业的资损防控

一、资损产生的原因 由于支付行业的特殊性与复杂性&#xff08;主要处理资金相关业务&#xff09;&#xff0c;支付公司处于资损的风口浪尖&#xff0c;最容易发生资损&#xff0c;可以说资损风险无处不在。 常规来说&#xff0c;资损原因主要可以分为以下三类&#xff1a; 1…

Linux设备驱动开发-字符设备

阅读引言&#xff1a; 从linux文件的种类、字符设备的创建、设备号、申请设备号、cdev对象和字符设备的对应关系、应用层调用到我们编写的设备驱动方法合集的流程。 目录 一、Linux文件的种类 二、Linux对设备的分类 三、驱动程序如何向应用层提供接口 四、Linux中设备的划…

微服务之LoadBalancer负载均衡服务调用

一、概述 1.1什么是负载均衡 LB&#xff0c;既负载均衡&#xff08;Load Balancer&#xff09;,是高并发、高可用系统必不可少的关键组件&#xff0c;其目标是尽力将网络流量平均分发到多个服务器上&#xff0c;以提高系统整体的响应速度和可用性。 负载均衡的主要作用 高并发…

华为机考入门python3--(15)牛客15-求int型正整数在内存中存储时1的个数

分类&#xff1a;二进制 知识点&#xff1a; int转二进制 binary bin(n)[2:] 题目来自【牛客】 def count_ones_in_binary(n): # 将输入的整数转换为二进制字符串 # bin(n)为0b11011binary bin(n)[2:]# 初始化计数器为0 count 0 # 遍历二进制字符串的每一位 fo…

2024年大唐杯备考

努力更新中…… 第一章 网络架构和组网部署 1.1 5G的网络整体架构 5G网络中的中传、回传、前传&#xff08;这里属于承载网的概念&#xff09; CU和DU之间是中传 BBU和5GC之间是回传 BBU和AAU之间是前传&#xff08;这个好记&#xff09; 这里竟然还藏了MEC&#xff08;…

YOLTV8 — 大尺度图像目标检测框架(欢迎star)

YOLTV8 — 大尺度图像目标检测框架【ABCnutter/YOLTV8: &#x1f680;】 针对大尺度图像&#xff08;如遥感影像、大尺度工业检测图像等&#xff09;&#xff0c;由于设备的限制&#xff0c;无法利用图像直接进行模型训练。将图像裁剪至小尺度进行训练&#xff0c;再将训练结果…

使用Python的Pillow库进行图像处理书法参赛作品

介绍&#xff1a; 在计算机视觉和图像处理领域&#xff0c;Python是一种强大而流行的编程语言。它提供了许多优秀的库和工具&#xff0c;使得图像处理任务变得轻松和高效。本文将介绍如何使用Python的wxPython和Pillow库来选择JPEG图像文件&#xff0c;并对选中的图像进行调整和…

STM32常见调试工具介绍

STM32的常见调试工具主要包括ST-LINK、USB转TTL、USB转485以及USB转CAN。这些工具在嵌入式系统开发、调试以及通信中发挥着重要的作用。 1.ST-LINK&#xff1a; ST-LINK是STMicroelectronics公司专为其STM32系列微控制器开发的调试和编程工具。既能仿真也能将编译好的程序下载…

python应用-os库操作目录

python自带的os模块提供了许多与操作系统交互的函数&#xff0c;适配多种操作系统&#xff0c;比如windows&#xff0c;mac&#xff0c;linux等&#xff0c;比如常用路径操作、进程管理、环境参数等都可通过os模块实现。 以下是自带的os.py中的前面一部分代码。 第一个红框中主…

asp.net core 网页接入微信扫码登录

创建微信开放平台账号&#xff0c;然后创建网页应用 获取appid和appsecret 前端使用的vue&#xff0c;安装插件vue-wxlogin 调用代码 <wxlogin :appid"appId" :scope"scope" :redirect_uri"redirect_uri"></wxlogin> <scri…

Qt快速入门(Opencv小案例之人脸识别)

Qt快速入门&#xff08;Opencv小案例之人脸识别&#xff09; 编译出错记录 背景 因为主要使用qt&#xff0c;并且官网下载的win版本的编译好的opencv默认是vc的&#xff0c;所以我们需要自己下载opencv的源码使用mingw自行编译&#xff0c;我直接使用的vscode。 报错 报错…

LabVIEW直流稳定电源自动化校准系统

LabVIEW直流稳定电源自动化校准系统 直流稳定电源正向着智能化、高精度、多通道、宽量程的方向发展。基于LabVIEW开发环境&#xff0c;设计并实现了一种直流稳定电源自动化校准系统&#xff0c;以提升校准过程的整体效能&#xff0c;实现自动化设备替代人工进行电源校准工作。…

YOLOv8 测试 5:Linux 中 Docker 部署 YOLOv8,Python 封装 API 接口,base64 图片处理

一、前言 记录时间 [2024-4-14] 系列文章简摘&#xff1a; Docker 学习笔记&#xff08;二&#xff09;&#xff1a;在 Linux 中部署 Docker&#xff08;Centos7 下安装 docker、环境配置&#xff0c;以及镜像简单使用&#xff09; API 接口简单使用&#xff08;二&#xff09;…

对常见FTP客户端/服务器的调查与分析

前言 主要是想看看常见的服务器和客户端是如何实现协议中要求的功能的&#xff0c;。 比如RF959要求的记录结构&#xff08;Record Structure&#xff09;、页结构&#xff08;Page Structure&#xff09;、Block Mode、Compress Mode&#xff0c;看起来就很抽象。 实测发现…

springBoot+vue编程中使用mybatis-plus遇到的问题

mybatis-plus中遇到的问题Code Companion Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)…