• 沒有找到結果。

3.3 开发规范与命令兼容

3.3.2 Lua 脚本规范

Lua是一种脚本语言,目的是为了嵌入应用程序中,为应用程序提供灵活的扩展和定制 功能。GaussDB(for Redis)使用的是Lua5.1.5版本,与开源Redis5.0使用的Lua版本是 一致的。

与开源 Redis Lua 的区别

1. EVAL/EVALSHA命令

命令格式:

EVAL script numkeys key [key …] arg [arg …]

EVALSHA sha1 numkeys key [key …] arg [arg …]

上述命令的语法与操作与开源Redis一致。用户需自己保证将脚本中使用到的 Redis key显式的通过key参数传入,而不是直接在脚本中编码,并且如果带有多 个key参数,则要求所有的key参数必须拥有相同的hash tag。

如果不遵循上述约束,则在Lua中执行涉及这些key的Redis操作时,可能会返回类 似“partition not found”的错误信息。

2. SCRIPT命令

SCRIPT命令包含了一组管理Lua脚本的子命令,具体可以通过SCRIPT HELP命令查 询具体的操作。

SCRIPT大部分命令都与开源Redis兼容,其中需要特别说明的命令如下:

SCRIPT KILL

GaussDB(for Redis)是多线程执行的环境,允许同时执行多个Lua脚本,执行 SCRIPT KILL,会终止所有正在运行的Lua脚本。

为了方便使用,GaussDB(for Redis)扩展了SCRIPT KILL命令,用户可以通过

‘SCRIPT KILL SHA1’来终止指定哈希值的脚本。若同一时间存在多个节点 在执行哈希值相同的脚本,那么这些脚本都会被终止。

另外,由于用户无法设置Lua超时时间(config set lua-time-limit),因此在 任意时刻执行SCRIPT KILL都能直接终止脚本,而不是等待脚本超时后才终 止。

SCRIPT DEBUG

目前GaussDB(for Redis)不支持DEBUG功能,所以该命令执行无效。

3. Lua脚本中执行Redis命令

与开源Redis一致,GaussDB(for Redis)的Lua环境中也提供了一个全局的

“redis”表,用于提供各类和Redis Server交互的函数。

如表3-7为GaussDB(for Redis)目前支持和不支持的操作列表。

3-7 函数列表

支持的操作 不支持的操作

● redis.call()

● redis.pcall()

● redis.sha1hex()

● redis.error_reply()

● redis.status_reply()

● redis.log()

● redis.LOG_DEBUG

● redis.LOG_VERBOSE

● redis.LOG_NOTICE

● redis.LOG_WARNING

● redis.replicate_commands()

● redis.set_repl()

● redis.REPL_NONE

● redis.REPL_AOF

● redis.REPL_SLAVE

● redis.REPL_REPLICA

● redis.REPL_ALL

● redis.breakpoint()

● redis.debug()

4. Lua执行环境限制

开源Redis对Lua脚本的执行有一定的限制,比如限制脚本操作全局变量,限制随 机函数的结果,限定能够使用的系统库和第三方库等。

GaussDB(for Redis)也继承了绝大多数的限制,但是针对如下情况,GaussDB(for Redis)与开源Redis存在差异:

Write Dirty

开源Redis规定,如果某个脚本已经执行了写操作,那么就不能被SCRIPT KILL停止执行,必须使用SHUTDOWN NOSAVE来直接关闭Redis Server。

GaussDB(for Redis)不支持执行SHUTDOWN命令,因此这条限制不会被执 行,用户仍然可以通过SCRIPT KILL来停止脚本的执行。

Random Dirty

由于主从复制的原因,开源Redis规定,若脚本执行了带有随机性质的命令

(Time, randomkey),则不允许再执行写语义的命令。

例如,如下Lua脚本:

local t = redis.call("time")

return redis.call("set", "time", t[1]);

当该脚本的执行传递到从节点时,Time命令获取到的时间一定晚于主节点,

因此从节点执行的Set命令的值就会和主节点产生冲突。开源Redis引入了 replicate_commands来允许用户决定这种场景下的行为模式。

对于GaussDB(for Redis)来说,由于没有主从的概念,数据在逻辑上只有一 份,因此也就不存在该限制。

Lua 脚本中禁用的命令列表

目前,在Lua脚本中禁用的GaussDB(for Redis)命令列表请参见命令兼容列表。