Redis Lua 脚本小学教程

本贴最后更新于 1709 天前,其中的信息可能已经时过境迁

Redis 提供了丰富的指令集,但是仍然不能满足所有场景,在一些特定场景下,需要自定义一些指定来完成某些功能。因此,Redis 提供了 Lua 脚本支持,用户可以自己编写脚本来实现想要的功能。

什么是 Lua?

Lua 是一种功能强大的,高效,轻量级,可嵌入的脚本语言。它是动态类型语言,通过使用基于寄存器的虚拟机解释字节码运行,并具有增量垃圾收集的自动内存管理,是配置,脚本和快速原型设计的最佳选择。

Redis 怎么执行 Lua 脚本

EVAL 命令

Redis 中可以使用 EVAL 命令执行相应的 Lua 脚本

> EVAL 'local val="Hello Jackey" return val' 0
"Hello Jackey"

你可以像这样在交互模式下执行 Lua 脚本,这样更方便处理错误。只是这样还不够,有时候,我们需要给 Lua 脚本传入一些参数。细心的同学一定注意到了,脚本的后面还有一个数字 0,它的意思的不传入参数。

那怎么传参数呢?

> EVAL 'local val=KEYS[1] return val.." "..ARGV[1]' 1 Hello Redis
"Hello Redis"

其实也很简单,传入的参数都是 kv 形式的,这个数字代表传入参数的 key 的数量,再后面就是 n 个 key 和 n 个 value。在脚本中,可以理解为从 KEYS 数组和 ARGV 数组中获取对应的值,下标是从 1 开始的。

上面例子中的两个点是 Lua 脚本中字符串连接的操作符

现在我们已经知道怎么在 Redis 中执行 Lua 脚本了,可是这样的脚本和 Redis 没有关系啊,怎么才能操作 Redis 中的数据呢?请继续看我表演

> get my_name
"Jackeyzhe"
> EVAL 'local val=ARGV[1].." "..redis.call("get",KEYS[1]) return val' 1 my_name Hello
"Hello Jackeyzhe"

使用 redis.call 或 redis.pcall(以后会提到)就可以操作 redis 了。

需要注意的是,如果返回下面的错误,说明要获取的 key 不存在

> EVAL 'local val=ARGV[1].." "..redis.call("get",KEYS[1]) return val' 1 me Hello
(error) ERR Error running script (call to f_eb11f8ddeeee07cc88d1f3bd103069284b83c5d8): @user_script:1: user_script:1: attempt to concatenate a boolean value

我们可以使用上面这种方法执行一些简单的 Lua 脚本,如果要执行更加复杂的 Lua 脚本,用 EVAL 命令就会显得臃肿且凌乱。所以 Redis 又提供了一种方法。

redis-cli --eval

我们可以先写一个 Lua 文件,然后使用 redis-cli 命令来执行。

local name=redis.call("get", KEYS[1])
local greet=ARGV[1]
local result=greet.." "..name
return result
> redis-cli --eval hello.lua my_name , Hello
"Hello Jackey"

这样,我们就可以先写一个.lua 文件,然后再使用 redis-cli 命令来执行了,看起来也不会很凌乱,使用这种方式传入参数时,不需要指定 key 的数量,而是用逗号分隔 key 和 argv。

EVALSHA

你以为到这就结束了吗?那就 too naive 了。如果我们在 Redis 交互模式中,想要执行脚本文件怎么办?每次都退出来,执行完再连接一次?这未免太麻烦了。Redis 提供了 EVALSHA 命令,使我们可以在交互模式执行脚本文件。

首先,需要上传脚本文件

$ redis-cli SCRIPT LOAD "$(cat hello.lua)"
"463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46"

会得到一串十六进制的数字,这是这个脚本的唯一标识。拿到这个数字后,表示我们已经将脚本上传到服务器了,接下来就可以使用这个标识来执行脚本了。

> EVALSHA 463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46 1 my_name Hello
"Hello Jackeyzhe"

终止脚本

Redis 中 Lua 脚本到默认执行时长是 5 秒,一般情况下脚本的执行时间都是毫秒级的,如果执行超时,脚本也不会停止,而是记录错误日志。

终止脚本执行的方法有两种

  1. 使用 KILL SCRIPT 命令

  2. 使用 SHUTDOWN NOSAVE 命令关闭服务器

不过不建议手动终止脚本

总结

本文简要介绍了什么是 Lua,以及 Redis 执行和终止 Lua 脚本的方法。如果都掌握了,那么恭喜你已经从 Lua 小学毕业了。在 Lua 中学你会学到 Redis 关于 Lua 命令的更详细介绍。

作者:Jackeyzhe
链接:https://www.jianshu.com/p/1f49438ea46f
来源:简书
著作权归作者所有。

  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖 • 62 关注
  • Lua
    17 引用 • 17 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...