Redis中运行lua

编程

Redis中运行lua

Redis中运行lua其实一直都没有什么特别的地方,特别要注意的其实就是Lua和Redis数据的交互.也就是下面记录的东西

其实这个东西在我的<分布式锁-基于Redis(不公平锁)>也有用到,可以参考那里

在Redis中将数据传给lua

# 注意,keys和argv可以同时传递给脚本,如果是在redis-cli运行脚本时,两者要用"空格,空格"分开,如果在交互式命令行运行是lua代码后使用一个数字确认有几个keys,keys后面的就是ARGV

KEYS 要传递的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 key3

1) "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

回到顶部