在Redis中使用Lua脚本

发表于2019-12-03,长度1608, 202个单词, 4分钟读完
Flag Counter

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

直接执行代码

redis使用eval命令 执行脚本,脚本使用引号包起来。单引号和双引号都可以,只要匹配就行。 脚本后面先跟一个数字表示有几个参数,没有参数也要写0。每一个参数都是一个键值对:第一个是键,会被加入KEYS数组, 第二个是值,会被加入ARGV数组。

manxi@bogon  ~  redis-cli
127.0.0.1:6379> eval 'local val=KEYS[1] return val.." 999  "..ARGV[1]' 1 key1 value1
"key1 999  value1"
127.0.0.1:6379>
127.0.0.1:6379> eval 'local a = KEYS[2] return KEYS[1]..a..ARGV[1]..ARGV[2]' 2 KEY1 V1 K2 V2
"KEY1V1K2V2"

上面例子中的两个点(..)是lua语言是的字符串拼接。

如果要操作Redis,可以使用redis.call方法:

127.0.0.1:6379> set name JimGreen
OK
127.0.0.1:6379> get name
"JimGreen"
127.0.0.1:6379> eval 'return KEYS[1].." "..ARGV[1].." "..redis.call("get", "name")' 1 kkk1 vvv1
"kkk1 vvv1 JimGreen"

如果redis获取失败,会报错:

127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> eval 'return KEYS[1].." "..ARGV[1].." "..redis.call("get", "name")' 1 kkk1 vvv1
(error) ERR Error running script (call to f_4d387d042bae7a82b70065cb64d202d3fe1c4791): @user_script:1: user_script:1: attempt to concatenate a boolean value

运行文件

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

manxi@bogon  ~  cat a.lua
local aname=redis.call('get', KEYS[1])
local hi=ARGV[1]
local res=hi..' '..aname
return res

然后执行:

manxi@bogon  ~  redis-cli --eval a.lua name , hello
"hello JimGreen"

可以看到比直接执行lua代码少传了参数个数,并且参数之间使用逗号分隔。注意:逗号前后都要有空格!

文件重用

我们在Redis交互模式中,如果想要执行脚本文件,每次都退出来,执行完再连接一次也太麻烦了。

Redis提供了EVALSHA命令,使我们可以在交互模式执行脚本文件。

先将lua文件上传到服务器:

manxi@bogon  ~ redis-cli script load "$(cat a.lua)"
"aafcf8dc0a5d873bff3ee3e774f603ac754fa572"

然后用返回的sha串执行:

127.0.0.1:6379> evalsha aafcf8dc0a5d873bff3ee3e774f603ac754fa572 1 name hello
"hello JimGreen"
Written on December 3, 2019
分类: dev, 标签: redis lua
如果你喜欢,请赞赏! davelet