百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

如何在Redis中执行Lua脚本? redisson lua

liuian 2024-12-25 14:00 41 浏览

Redis中需要执行Lua脚本的场景

Redis中每条命令都是原子性的,即执行结果要么全部成功要么全部失败。在某些业务场景下,需要执行多条命令,并且要保证多条命令的原子性。这时,如果命令逐条执行,显然是不能保证原子性的。有同学可能会想到使用Redis的事务功能,事务是可以保证原子性,但是受限于命令的功能,有些场景下并不能实现想要的功能。

使用执行Lua脚本的方式可以解决以上问题,Lua脚本整体上在Redis中是原子性的。

在Redis中执行Lua脚本

在Redis中通过EVAL命令来执行Lua脚本,基本语法如下:

redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...] 

参数说明:

  • script: 参数是一段Lua脚本程序。脚本不必(也不应该)定义为一个 Lua 函数。
  • numkeys: 用于指定键名参数的个数。
  • key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
  • arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

获取指定key的值,相当于于 GET somekey

EVAL "return redis.call('GET', KEYS[1])" 1 somekey

再看一个LPUSH的例子,相当于 LPUSH somelist 1 2 3

EVAL "return redis.call('LPUSH',KEYS[1], ARGV[1], ARGV[2], ARGV[3])" 1 somelist 1 2 3

简单说下Redis执行lua脚本相关的其他几个命令:

  • EVALSHA命令根据给定的SHA1,执行缓存在服务器中的脚本。
  • SCRIPT EXISTS命令用于检查指定SHA1值对应的脚本是否在Redis缓存中。
  • SCRIPT FLUSH命令用于清除所有的缓存脚本。
  • SCRIPT KILL命令用于杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限循环的脚本。SCRIPT KILL 执行之后,当前正在运行的脚本会被杀死,执行这个脚本的客户端会从 EVAL 命令的阻塞当中退出,并收到一个错误作为返回值

Lua脚本中调用Reids命令

调用Redis命令,当执行出错时,该方法会直接返回错误,并退出

redis.call(redisCommand, key, argv...)

调用Redis命令,当执行出错时,记录错误信息,并继续执行

redis.pcall(redisCommand, key, argv...)

记录日志,写入到Redis配置的日志文件中,日志级别有四种,分别是redis.LOG_DEBUG、redis.LOG_VERBOS、redis.LOG_NOTICE和redis.LOG_WARNING

redis.log(logLevel, message)

计算输入字符串的sha1哈希值

redis.sha1hex(arvg)

Lua与Redis类型转换

Redis调用Lua脚本,脚本执行完成后将结果返回给Redis,Redis再将结果返回给客户端。这个过程中会出现Redis执行结果类型到Lua数据类型的转换,然后Lua类型到Redis类型的转换。Redis类型到Lua类型转换关系如下:

Redis返回的数据类型

Lua数据类型

integer(整数回复)

number(数字类型)

bulk replay(字符串)

string(字符串类型)

多行字符串

table(数组形式)

status(状态回复)

table(只有一个ok字段的数组)

error(错误回复)

table(只有一个err字段的数组)

Lua类型到Redis类型转换关系如下:

Lua数据类型

Redis返回数据类型

number(数字类型)

integer(整数回复)

string(字符串类型)

bulk replay(字符串)

table(数组形式)

多行字符串

table(只有一个ok字段的数组)

status(状态回复)

table(只有一个err字段的数组)

error(错误回复)

相关推荐

10种常见的MySQL错误,你可中招?

【51CTO.com快译】如果未能对MySQL8进行恰当的配置,您非但可能遇到无法顺利访问、或调用MySQL的窘境,而且还可能给真实的应用生产环境带来巨大的影响。本文列举了十种MySQL...

MySQL主从如何保证数据一致性

MySQL主从(主备)搭建请点击基于Spring的数据库读写分离。MySQL主备基本原理假设主备切换前,我们的主库是节点A,节点B是节点A的备库,客户端的读写都是直接访问节点A,节点B只是将A的更新同...

MySQL低版本升级操作流程

(关注“数据库架构师”公众号,提升数据库技能,助力职业发展)0-升级背景MySQL5.5发布于2010年,至今已有十年历史,官方已经停止更新。2008年发布的MySQL5.1版本,在2018年...

MySQL数据库知识

MySQL是一种关系型数据库管理系统;那废话不多说,直接上自己以前学习整理文档:查看数据库命令:(1).查看存储过程状态:showprocedurestatus;(2).显示系统变量:show...

Mysql 8.4数据库安装、新建用户和数据库、表单

1、下载MySQL数据库yuminstall-ywgetperlnet-toolslibtirpc#安装wget和perl、net-tools、libtirpcwgethtt...

mysql8.0新功能介绍

MySQL8.0新特性集锦一、默认字符集由latin1变为utf8mb4在8.0版本之前,默认字符集为latin1,utf8指向的是utf8mb3,8.0版本默认字符集为utf8mb4,utf8默...

全网最详细解决Windows下Mysql数据库安装后忘记初始root 密码方法

一、准备重置root的初始化密码Win+R键启动命令输入窗口;输入cmd打开命令执行窗口;##界面如下##输入命令:netstopmysqld#此操作会停止当前运行的...

互联网大厂面试:MySQL使用grant授权后必须flush privilege吗

从我上大学时,数据库概论老师就告诉我,MySQL使用grant对用户授权之后,一定记得要用flushprivilege命令刷新缓存,这样才能使赋权命令生效。毕业工作以后,在很多的技术文档上,仍然可以...

# mysql 8.0 版本无法使用 sqlyog 等图形界面 登录 的解决方法

30万以下的理想L6来了##mysql8.0版本无法使用sqlyog等图形界面登录的解决方法当我们在cmd下登录mysql时正常时,用sqlyog等图形界面连接数据库时却...

MySQL触发器介绍

前言:在学习MySQL的过程中,可能你了解过触发器的概念,不清楚各位是否有详细的去学习过触发器,最近看了几篇关于触发器的文档,分享下MySQL触发器相关知识。1.触发器简介触发器即trigg...

管理员常用的MySQL命令汇总(一)

以下是管理员常用的MySQL命令:以管理员身份连接到MySQL:mysql-uroot-p创建新的MySQL用户:CREATEUSER'username'@'...

Linux(CentOS) 在线安装MySQL8.0和其他版本,修改root密码

一:安装MySQL数据库1),下载并安装MySQL官方的YumRepositorymysql官方仓库地址:https://dev.mysql.com/downloads/repo/yum/选择自...

解决 MySQL 8.0 一直拒绝 root 登录问题

Accessdeniedforuser'root'@'localhost'(usingpassword:YES)这个错误在网上搜一下,能看到非常多的此类...

大模型MCP之MYSQL安装

前言学习大模型的时候需要一个mysql,原因还是在公司使用电脑的时候不允许按照Docker-Desktop,我的宿主机其实是MAC,我习惯上还是在centsos上面安装,就发现这件过去很简单的事情居然...

MySQL ERROR 1396

ERROR1396(HY000):OperationCREATEUSERfailedfor'usera'@'%'问题描述mysql>create...