- 文档首页
缓存数据库 Redis 版
最佳实践
Lua 脚本使用指南
Lua 脚本使用指南
缓存数据库 Redis 版支持通过 Lua 脚本来处理 CAS(compare-and-swap)命令,满足 Redis 原子性操作需求,提升 Redis 性能。本文介绍通过 Redis 使用 Lua 脚本的基本语法与使用限制和建议。
Lua 脚本命令
下表列举了缓存数据库 Redis 版支持的 Lua 脚本命令和功能简介。
Lua 脚本命令语法
EVAL script numkeys [key [key ...]] [arg [arg ...]]
说明
- 通过 EVAL 命令执行 Lua 脚本时,系统会同时将该脚本缓存至 Redis 实例中。关于 EVAL 命令的详细说明,请参见 EVAL。
- 推荐将脚本中所访问的 Key 通过 KEYS[] 参数显式传入,而不是将参数编码进脚本中,因为过多类似行为会导致实例内存使用量上升且无法及时回收,极端情况下会导致实例主库与备库内存溢出(Out of Memory),造成数据丢失。
- 示例 1:通过 EVAL 命令执行如下 Lua 脚本,用于设置 Key=department,value=Game 的字符串,具体命令如下。
EVAl "return redis.call('SET',KEYS[1],ARGV[1])" 1 department Game
- 示例 2:通过 EVAL 命令执行如下 Lua 脚本,用于获取一个 Key=department 的字符串的值,具体命令如下。
EVAl "return redis.call('GET',KEYS[1])" 1 department
- 当通过 EVAL 命令执行较长的 Lua 脚本时,会占用较多带宽。为避免上述问题,您可以使用 EVALSHA 命令通过 Lua 脚本的 sha1 值来执行对应脚本。
EVALSHA sha1 numkeys [key [key ...]] [arg [arg ...]]
说明
使用 EVALSHA 命令时,若 sha1 值对应的脚本未缓存至 Redis 中,Redis 会返回 NOSCRIPT No matching script. 报错。请先通过 EVAL 或 SCRIPT LOAD 命令将目标脚本缓存至 Redis 中再执行 EVALSHA 命令。关于 EVALSHA 命令的详细说明,请参见 EVALSHA。 EVALSHA 620cd258c2c9c88c9d10db67812ccf663d96bdc6 1 department
- 将 Lua 脚本缓存至 Redis 实例中,但并不立即执行这个脚本,而是会返回该脚本的 sha1 值。
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 值间用空格分隔。返回结果的取值范围如下:
SCRIPT EXISTS 620cd258c2c9c88c9d10db67812ccf663d96bdc6 620cd258c2c9c88c9d10db67812ccf663d96bdc7
- 终止正在运行的 Lua 脚本。该命令主要用于终止运行时间过长的脚本,例如由于错误而进入无限循环的脚本。
说明
- 为保障数据原子性,仅当指定脚本没有执行过任何写操作时,SCRIPT KILL 命令才会生效。
- 执行 SCRIPT KILL 命令后,正在执行 Lua 脚本的客户端将会看到对应脚本命令所返回的错误。关于 SCRIPT KILL 命令的详细说明,请参见 SCRIPT KILL。
- 清空当前 Redis 实例中所有的 Lua 脚本缓存。
SCRIPT FLUSH [ASYNC | SYNC]
说明
- Redis 支持指定执行 SCRIPT FLUSH 命令后缓存的刷新模式,取值范围如下:
- 该命令会清空当前 Redis 实例中所有的 Lua 脚本缓存,建议清空前先备份 Lua 脚本。关于 SCRIPT FLUSH 命令的详细说明,请参见 SCRIPT FLUSH。
Lua 脚本使用限制
Lua 脚本使用建议
- 建议将脚本中所访问的 Key 通过 KEYS[] 参数显式传入,而不是将参数编码进脚本中,因为过多类似行为会导致实例内存使用量上升且无法及时回收,极端情况下会导致实例主库与备库内存溢出(Out of Memory),造成数据丢失。
- 建议在 Lua 脚本中增加 redis.replicate_commands(); 参数,来指定数据同步模式为基于实际命令的模式,避免出现主从数据不一致的问题。
- 加载 Lua 脚本会耗费较多的计算资源,建议尽量复用 Lua 脚本,可以帮助降低网络开销和减少需要缓存的脚本数量。
- 建议在 Lua 脚本中仅写入简单的命令操作,涉及原子性的复杂操作建议使用事务命令。
- 建议不要在 Lua 脚本中写大量的循环,防止脚本执行超时或执行出错,甚至导致 Redis 实例卡死。
- 建议不要在 Lua 脚本中使用一些非官方的 SDK(如 Redisson),防止出现一些未知的问题甚至风险。
最近更新时间:2025.12.23 10:30:25