缓存数据库 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 脚本时的限制也不同。其中:
KEYS
数组来传递;redis.call/pcall
中调用的 Redis 命令,Key 的位置必须是 KEYS
数组。numkeys
的取值需大于等于 1。command arguments invalid
报错。若需要提高默认上限(最多可提升至 100,000),请提交工单联系技术支持。command arguments invalid
报错。若需要提高默认上限(最多可提升至 100,000),请提交工单联系技术支持。缓存数据库 Redis 版限制了部分命令不可在 Lua 脚本中使用。更多关于 Lua 脚本中支持使用的命令详情,请参见命令支持。
KEYS[]
参数显式传入,而不是将参数编码进脚本中,因为过多类似行为会导致实例内存使用量上升且无法及时回收,极端情况下会导致实例主库与备库内存溢出(Out of Memory),造成数据丢失。redis.replicate_commands();
参数,来指定数据同步模式为基于实际命令的模式,避免出现主从数据不一致的问题。