Redis中运行lua
Redis中运行lua
Redis中运行lua其实一直都没有什么特别的地方,特别要注意的其实就是Lua和Redis数据的交互.也就是下面记录的东西
其实这个东西在我的<分布式锁-基于Redis(不公平锁)>也有用到,可以参考那里
在Redis中将数据传给lua
# 注意,keys和argv可以同时传递给脚本,如果是在redis-cli运行脚本时,两者要用"空格,空格"分开,如果在交互式命令行运行是lua代码后使用一个数字确认有几个keys,keys后面的就是ARGVKEYS 要传递的Key,可以为N个,在lua脚本中通过KEYS[1], KEYS[2]获取(没有0)
ARGV 要传递的参数,在lua脚本中通过ARGV[1], ARGV[2]获取(没有0)
在Redis中运行lua
redis-cli自动提示的案例
127.0.0.1:6379> eval script numkeys key [key ...] arg [arg ...]- eval 执行lua脚本
- script lua脚本
- numkeys KEYS的个数,标识从这里开始后面有多少个是kyes,比如3代表后面三个都是keys.如果不打算有keys,要写0
- key KEYS可以是N个,用空格隔开
- arg ARGV可以是N个,用空格隔开
执行案例
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],KEYS[3]}" 3 key1 key2 key31) "key1"
2) "key2"
3) "key3"
# 注意使用ARGV时,这里的argv1前面的0一定要写对,否则会取错值的,这里的0代表没有设置Keys,全部都是ARGV
127.0.0.1:6379> eval "return {ARGV[1],ARGV[2],ARGV[3]}" 0 argv1 argv2 argv3
1) "argv1"
2) "argv2"
3) "argv3"
# 注意使用ARGV时,这里的key1前面的3一定要写对,否则会取错值的,这里的3代表,从这里开始后面三个都是keys
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],KEYS[3],ARGV[1],ARGV[2]}" 3 key1 key2 key3 argv1 argv2
1) "key1"
2) "key2"
3) "key3"
4) "argv1"
5) "argv2"
运行脚时再使用Redis
在Redis中使用eval之类的命令调用lua脚本, 脚本中可以使用下面方式调用Redis
redis.call() 执行Redis命令,比如hset,set之类的命令,call会触发Lua中的异常redis.pcall() 执行Redis命令,比如hset,set之类的命令,将自动捕获所有能检测到的错误并以表的形式返回错误内容
使用redis-cli --eval
直接将lua脚本在Redis中运行,同时在脚本中set了两个值
运行命令脚本,注意: 调用脚本时传参在Key和ARGV之间用逗号隔开,逗号两边要有空格
------ Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by liuhao.
--- DateTime: 2020/4/9 2:26 上午
---
-- redis-cli --eval ./test.lua name age , liuhao 20
-- 设置name,相当于 set name liuhao
local setName = redis.call("set",KEYS[1],ARGV[1])
-- 这里也可以判断setName.err
if tostring(setName.ok) ~= "OK" then -- setName.ok是setName["ok"]的另一种使用方式
return "set name failed"
end
-- 设置age,相当于 set age 20
local setAge = redis.call("set",KEYS[2],ARGV[2])
-- 这里也可以判断setAge.err
if tostring(setAge.ok) ~= "OK" then
return "set age failed"
end
return "whole set success"
注意这里调用脚本时传参在Key和ARGV之间用逗号隔开,逗号两边要有空格
~/Desktop/tmp ⌚ 3:49:17$ redis-cli --eval ./test.lua name age , liuhao 20
"whole set success"
特别注意-Redis和Lua的数据类型转换
注意
- set 返回table,通过 setResult.ok和setResult.err可以得到结果,然后进行判断
- incr 返回number,直接接可以接到,进行判断
Redis数据类型到 Lua 的转换表
- Redis integer reply -> Lua number / Redis 整数转换成 Lua 数字
- Redis bulk reply -> Lua string / Redis bulk 回复转换成 Lua 字符串
- Redis multi bulk reply -> Lua table (may have other Redis data types nested) / Redis 多条 bulk 回复转换成 Lua 表,表内可能有其他别的 Redis 数据类型
- Redis status reply -> Lua table with a single ok field containing the status / Redis 状态回复转换成 Lua 表,表内的 ok 域包含了状态信息
- Redis error reply -> Lua table with a single err field containing the error / Redis 错误回复转换成 Lua 表,表内的 err 域包含了错误信息
- Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type / Redis 的 Nil 回复和 Nil 多条回复转换成 Lua 的布尔值 false
Lua 数据类型到 Redis 的转换表。
- Lua number -> Redis integer reply (the number is converted into an integer) / Lua 数字转换成 Redis 整数
- Lua string -> Redis bulk reply / Lua 字符串转换成 Redis bulk 回复
- Lua table (array) -> Redis multi bulk reply (truncated to the first nil inside the Lua array if any) / Lua 表(数组)转换成 Redis 多条 bulk 回复
- Lua table with a single ok field -> Redis status reply / 一个带单个 ok 域的 Lua 表,转换成 Redis 状态回复
- Lua table with a single err field -> Redis error reply / 一个带单个 err 域的 Lua 表,转换成 Redis 错误回复
- Lua boolean false -> Redis Nil bulk reply. / Lua 的布尔值 false 转换成 Redis 的 Nil bulk 回复
从 Lua 转换到 Redis 有一条额外的规则,这条规则没有和它对应的从 Redis 转换到 Lua 的规则:
- Lua boolean true -> Redis integer reply with value of 1. / Lua 布尔值 true 转换成 Redis 整数回复中的 1
以上是 Redis中运行lua 的全部内容, 来源链接: utcz.com/z/515265.html