缓存数据库 Redis 版支持通过 Lua 脚本来处理 CAS(compare-and-swap)命令,满足 Redis 原子性操作需求,提升 Redis 性能。本文介绍通过 Redis 使用 Lua 脚本的基本语法与使用限制和建议。
下表列举了缓存数据库 Redis 版支持的 Lua 脚本命令和功能简介。
命令 | 功能说明 |
---|---|
EVAL | 执行给定的脚本和参数,并返回结果。 |
EVALSHA | 当通过 EVAL 命令执行较长的 Lua 脚本时,会占用较多带宽。为避免上述问题,您可以使用 EVALSHA 命令通过 Lua 脚本的 sha1 值来执行对应脚本。 |
SCRIPT LOAD | 将 Lua 脚本缓存至 Redis 实例中,但并不立即执行这个脚本,而是会返回该脚本的 sha1 值。 |
SCRIPT EXISTS | 通过指定脚本的 sha1 值,确认该值所对应的脚本是否已缓存至 Redis 实例中。支持同时传入多个脚本的 sha1 值进行确认,多个 sha1 值间用空格分隔。 |
终止正在运行的 Lua 脚本。 | |
SCRIPT FLUSH | 清空当前 Redis 实例中所有的 Lua 脚本缓存。 |
功能
执行指定 Lua 脚本并返回对应结果。
语法
EVAL script numkeys [key [key ...]] [arg [arg ...]]
参数具体说明如下表。
参数 | 说明 |
---|---|
| Lua 脚本的源代码。Redis 支持通过
|
| 指定
|
说明
KEYS[]
参数显式传入,而不是将参数编码进脚本中,因为过多类似行为会导致实例内存使用量上升且无法及时回收,极端情况下会导致实例主库与备库内存溢出(Out of Memory),造成数据丢失。示例
示例 1:通过 EVAL 命令执行如下 Lua 脚本,用于设置 Key=department
,value=Game
的字符串,具体命令如下。
EVAl "return redis.call('SET',KEYS[1],ARGV[1])" 1 department Game
返回示例如下。
OK
示例 2:通过 EVAL 命令执行如下 Lua 脚本,用于获取一个 Key=department
的字符串的值,具体命令如下。
EVAl "return redis.call('GET',KEYS[1])" 1 department
返回示例如下。
"Game"
功能
当通过 EVAL 命令执行较长的 Lua 脚本时,会占用较多带宽。为避免上述问题,您可以使用 EVALSHA 命令通过 Lua 脚本的 sha1
值来执行对应脚本。
语法
EVALSHA sha1 numkeys [key [key ...]] [arg [arg ...]]
参数具体说明如下表。
参数 | 说明 |
---|---|
sha1 | Lua 脚本对应的 SHA1 校验和。 |
| 指定
|
说明
使用 EVALSHA 命令时,若 sha1
值对应的脚本未缓存至 Redis 中,Redis 会返回 NOSCRIPT No matching script.
报错。请先通过 EVAL 或 SCRIPT LOAD 命令将目标脚本缓存至 Redis 中再执行 EVALSHA 命令。关于 EVALSHA 命令的详细说明,请参见 EVALSHA。
示例
EVALSHA 620cd258c2c9c88c9d10db67812ccf663d96bdc6 1 department
返回结果示例如下。
"Game"
功能
将 Lua 脚本缓存至 Redis 实例中,但并不立即执行这个脚本,而是会返回该脚本的 sha1
值。
语法
SCRIPT LOAD script
关于 SCRIPT LOAD 命令的详细说明,请参见 SCRIPT LOAD。
示例
SCRIPT LOAD "return redis.call('GET',KEYS[1])" 1 department "return redis.call('GET',KEYS[1])" 1 department
返回结果示例如下。
"620cd258c2c9c88c9d10db67812ccf663d96bdc6"
功能
通过指定脚本的 sha1
值,确认该值所对应的脚本是否已缓存至 Redis 实例中。
语法
SCRIPT EXISTS sha1 [sha1 ...]
说明
sha1
值进行确认,多个 sha1
值间用空格分隔。返回结果的取值范围如下:
1
:脚本已存在。0
:脚本不存在。示例
SCRIPT EXISTS 620cd258c2c9c88c9d10db67812ccf663d96bdc6 620cd258c2c9c88c9d10db67812ccf663d96bdc7
返回结果示例如下。
1) (integer) 1 2) (integer) 0
功能
终止正在运行的 Lua 脚本。该命令主要用于终止运行时间过长的脚本,例如由于错误而进入无限循环的脚本。
语法
SCRIPT KILL
说明
示例
SCRIPT KILL
返回结果示例如下。
OK
功能
清空当前 Redis 实例中所有的 Lua 脚本缓存。
语法
SCRIPT FLUSH [ASYNC | SYNC]
说明
SYNC
(默认值):同步刷新缓存。ASYNC
:异步刷新缓存。示例
SCRIPT FLUSH
返回示例如下。
OK
缓存数据库 Redis 版的实例类型不同,使用 Lua 脚本时的限制也不同。其中:
启用分片集群的 Redis 实例
KEYS
数组来传递;redis.call/pcall
中调用的 Redis 命令,Key 的位置必须是 KEYS
数组。numkeys
的取值需大于等于 1。command arguments invalid
报错。若需要提高默认上限(最多可提升至 100000),请提交工单联系技术支持。不启用分片集群的 Redis 实例
不启用分片集群的 Redis 实例在使用 Lua 脚本时,Lua 脚本中 Key 参数的个数默认上限为 100。当 Key 个数超过上限时,会出现 command arguments invalid
报错。若需要提高默认上限(最多可提升至 100000),请提交工单联系技术支持。
缓存数据库 Redis 版限制了部分命令不可在 Lua 脚本中使用。更多关于 Lua 脚本中支持使用的命令详情,请参见命令支持。
KEYS[]
参数显式传入,而不是将参数编码进脚本中,因为过多类似行为会导致实例内存使用量上升且无法及时回收,极端情况下会导致实例主库与备库内存溢出(Out of Memory),造成数据丢失。redis.replicate_commands();
参数,来指定数据同步模式为基于实际命令的模式,避免出现主从数据不一致的问题。