分类 Redis 下的文章

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调试