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的值。
EVAL "return redis.call('GET', KEYS[1])" 1 aa
(2)、EVALSHA
用于执行已经加载到 Redis 中的 Lua 脚本。你可以先使用 SCRIPT LOAD
将脚本加载到 Redis 中,然后通过其 SHA1 校验和来调用它。这样可以避免每次都传输整个脚本文本,节省带宽和解析时间。
示例:
首先加载脚本:
SCRIPT LOAD "return redis.call('GET', KEYS[1])"
然后使用EVALSHA执行:
EVALSHA d3c21d0c2b9ca22f82737626a27bcaf5d288f99f 1 aa
4、Lua 脚本中的Redis API
在 Lua 脚本中,可以使用 redis.call() 或 redis.pcall() 来调用 Redis 命令。这两个函数的区别在于错误处理方式:
(1)、redis.call():如果调用的 Redis 命令失败,会抛出错误并终止整个脚本的执行。
(2)、redis.pcall():即使调用的 Redis 命令失败,也会返回一个包含错误信息的表,而不是抛出错误,允许你继续执行脚本中的其他逻辑。
示例:
获取一个键的值,如果不存在则设置默认值并返回
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来执行这段脚本,即使有错误也可以继续执行。
学海无涯苦作舟!!!