Redis篇-5--原理篇4--Lua脚本

1、概述

Redis 支持使用 Lua 脚本来执行复杂的操作,这为 Redis 提供了更强的灵活性和性能优化能力。通过 Lua 脚本,你可以在服务器端执行一系列命令,而不需要多次往返客户端与服务器之间,从而减少了网络延迟并提高了效率。此外,Lua 脚本是原子性的,这意味着在脚本执行期间,其他客户端的请求不会被处理,确保了数据的一致性。

2、使用Lua脚本的好处

(1)、减少网络往返:将多个命令封装到一个脚本中,可以减少客户端与 Redis 服务器之间的通信次数。

(2)、提高性能:由于减少了网络延迟,并且脚本是在 Redis 服务器端直接执行的,因此可以显著提高性能。

(3)、保证原子性:Lua 脚本在执行时是原子性的,即在脚本执行期间,不会有其他命令插入,确保了操作的原子性和一致性。

(4)、复杂逻辑处理:可以实现更复杂的逻辑,比如条件判断、循环等,这些在普通的 Redis 命令中是无法实现的。

3、执行Lua脚本的方式

Redis 提供了两个命令来执行Lua脚本:

(1)、EVAL

作用:

用于执行一次性的Lua脚本。你需要提供完整的Lua代码作为参数,并指定脚本要操作的键以及可选的额外参数。
语法:

EVAL script numkeys key [key ...] [arg [arg ...]]
参数说明:

  • EVAL:这是Redis提供的命令,用于执行Lua脚本。
  • script:Lua脚本的内容,作为字符串传递给EVAL
  • numkeys:表示脚本中使用的键的数量。这些键将通过KEYS数组传递给Lua脚本。
  • key [key ...]:实际的键名,按照顺序对应 KEYS 数组中的元素。
  • arg [arg ...]:可选的额外参数,它们会通过 ARGV 数组传递给 Lua 脚本。

示例:

使用lua脚本打印aa的值。

java 复制代码
EVAL "return redis.call('GET', KEYS[1])" 1 aa

(2)、EVALSHA

用于执行已经加载到 Redis 中的 Lua 脚本。你可以先使用 SCRIPT LOAD 将脚本加载到 Redis 中,然后通过其 SHA1 校验和来调用它。这样可以避免每次都传输整个脚本文本,节省带宽和解析时间。

示例:
首先加载脚本:

java 复制代码
SCRIPT LOAD "return redis.call('GET', KEYS[1])"

然后使用EVALSHA执行:

java 复制代码
EVALSHA d3c21d0c2b9ca22f82737626a27bcaf5d288f99f 1 aa

4、Lua 脚本中的Redis API

在 Lua 脚本中,可以使用 redis.call() 或 redis.pcall() 来调用 Redis 命令 。这两个函数的区别在于错误处理方式:

(1)、redis.call():如果调用的 Redis 命令失败,会抛出错误并终止整个脚本的执行。

(2)、redis.pcall():即使调用的 Redis 命令失败,也会返回一个包含错误信息的表,而不是抛出错误,允许你继续执行脚本中的其他逻辑。

示例:

获取一个键的值,如果不存在则设置默认值并返回

java 复制代码
EVAL "local value = redis.call('GET', KEYS[1]) \
                       if not value then \
                           redis.call('SET', KEYS[1], ARGV[1]) \
                           return ARGV[1] \
                       else \
                           return value \
                       end" 1 mykey "default_haha"

实际这里我没有设置过mykey,所以这段lua脚本会设置mykey为default_haha并发挥这个值。因为没有语法错误这里就正常执行了。也可以直接使用redisp.call来执行这段脚本,即使有错误也可以继续执行。

学海无涯苦作舟!!!

相关推荐
web1368856587119 分钟前
Spring Boot 中使用 @Transactional 注解配置事务管理
数据库·spring boot·sql
骷大人1 小时前
mysql开启配置binlog
数据库·mysql
Yolo_nn1 小时前
MySQL_第14章_存储过程与函数
数据库·mysql·存储过程·函数
GDDGHS_2 小时前
Flink自定义数据源
大数据·数据库·flink
Milk夜雨2 小时前
数据库进阶教程:结合编程实现动态数据操作
数据库·python·adb
是十一月末2 小时前
Linux的基本功能和命令
linux·服务器·开发语言·数据库
MavenTalk2 小时前
Spring Cloud Alibaba:一站式微服务解决方案
java·数据库·spring boot·spring cloud·微服务·netflix
荼蘼_3 小时前
宝塔内设置redis后,项目以及RedisDesktopManager客户端连接不上!
数据库·redis·缓存
m_merlon3 小时前
Fastapi教程:使用aioredis异步访问redis
redis·fastapi