Redis提供了丰富的指令集,可是仍然不能知足全部场景,在一些特定场景下,须要自定义一些指定来完成某些功能。所以,Redis提供了Lua脚本支持,用户能够本身编写脚原本实现想要的功能。redis
Lua是一种功能强大的,高效,轻量级,可嵌入的脚本语言。它是动态类型语言,经过使用基于寄存器的虚拟机解释字节码运行,并具备增量垃圾收集的自动内存管理,是配置,脚本和快速原型设计的最佳选择。数组
Redis中可使用EVAL命令执行相应的Lua脚本bash
> EVAL 'local val="Hello Jackey" return val' 0
"Hello Jackey"
复制代码
你能够像这样在交互模式下执行Lua脚本,这样更方便处理错误。只是这样还不够,有时候,咱们须要给Lua脚本传入一些参数。细心的同窗必定注意到了,脚本的后面还有一个数字0,它的意思的不传入参数。服务器
那怎么传参数呢?ui
> EVAL 'local val=KEYS[1] return val.." "..ARGV[1]' 1 Hello Redis
"Hello Redis"
复制代码
其实也很简单,传入的参数都是kv形式的,这个数字表明传入参数的key的数量,再后面就是n个key和n个value。在脚本中,能够理解为从KEYS数组和ARGV数组中获取对应的值,下标是从1开始的。lua
上面例子中的两个点是Lua脚本中字符串链接的操做符spa
如今咱们已经知道怎么在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不存在code
> 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又提供了一种方法。
咱们能够先写一个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。
你觉得到这就结束了吗?那就too naive了。若是咱们在Redis交互模式中,想要执行脚本文件怎么办?每次都退出来,执行完再链接一次?这未免太麻烦了。Redis提供了EVALSHA命令,使咱们能够在交互模式执行脚本文件。
首先,须要上传脚本文件
$ redis-cli SCRIPT LOAD "$(cat hello.lua)"
"463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46"
复制代码
会获得一串十六进制的数字,这是这个脚本的惟一标识。拿到这个数字后,表示咱们已经将脚本上传到服务器了,接下来就可使用这个标识来执行脚本了。
> EVALSHA 463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46 1 my_name Hello
"Hello Jackeyzhe"
复制代码
Redis中Lua脚本到默认执行时长是5秒,通常状况下脚本的执行时间都是毫秒级的,若是执行超时,脚本也不会中止,而是记录错误日志。
终止脚本执行的方法有两种
不过不建议手动终止脚本
本文简要介绍了什么是Lua,以及Redis执行和终止Lua脚本的方法。若是都掌握了,那么恭喜你已经从Lua小学毕业了。在Lua中学你会学到Redis关于Lua命令的更详细介绍。