Redis Lua 脚本
Redis Lua解析器支持的库
- base lib.
- table lib.
- string lib.
- math lib.
- debug lib.
- bitop lib.
- redis.sha1hex function.
- struct lib. 外部库
- cjson lib. 外部库
- cmsgpack lib. 外部库
转换规则:Redis <-> Lua
- int <-> number
- bulk/str <-> str
- multi bulk <-> table,表内可以有其他数据类型
- status <-> table,表内ok包含状态信息
- error <-> table,表内err包含错误信息
- Nil/Nil multi <-> false
- 1 <-> true
EVAL "return true" 0
(integer) 1
EVAL "return false" 0
(nil)
使用 EVAL 或 EVALSHA
help @scripting
# vim demo.lua
local _M = {
KEYS[1],KEYS[2],
ARGV[1],ARGV[2]
}
return _M
redis-cli --eval demo.lua key1 key2 , first second
EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
SCRIPT LOAD "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"
"a42059b356c875f0717db19a51f6aaca9ae659ea"
EVALSHA a42059b356c875f0717db19a51f6aaca9ae659ea 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
Lua脚本的阻塞
- 单实例,阻塞不能对缓存有任何操作
集群
- 阻塞的主节点上,阻塞;
- 阻塞的主节点的从节点上,重定向到主节点,阻塞。从节点可查看;
- 阻塞的节点上操作非阻塞的节点的缓存没有影响,可重定向到其他主机实例进行缓存操作
- 不影响集群中非阻塞实例中的缓存操作,包括lua脚本的执行
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
SCRIPT KILL:仅能中断对数据集没有修改的操作。当中出现写入操作时无效
SHUTDOWN NOSAVE:硬中断并关闭服务。数据不会改变。
遇到死循环阻塞时,为何SCRIPT KILL仍可操作?
Lua引擎提供各种各样的钩子函数。比如每执行10W条指令执行一次某个hook函数。Redis在钩子函数里会忙里偷闲的处理客户端的请求,并且在发现超时5s后才真正执行。
Lua脚本内的redis调用
redis.call()
执行命令过程发生错误时停止执行,并返回一个脚本错误信息。
redis.pcall()
同上。仅区别于发生错误时。出错时并不引发(raise)错误,而是返回一个带 err 域的 Lua 表(table),用于表示错误
redis.log(loglevel,message)
记录在Redis日志中
loglevel
- redis.LOG_DEBUG
- redis.LOG_VERBOSE
- redis.LOG_NOTICE
- redis.LOG_WARNING
EVAL "redis.log(redis.LOG_NOTICE, 'HELLO REDIS LOG')" 0
redis.breakpoint()
打断点。配合--ldb调试