Redis Lua 脚本详解:原子性操作与高效执行
Redis 对 Lua 脚本的支持是其高级特性之一,通过将多个命令封装为脚本,可实现原子性执行并减少网络往返开销,尤其适合复杂业务逻辑(如分布式锁、计数器累加等)。本文基于 Redis 6.0.10 版本,详解 Lua 脚本的使用方法、核心命令及最佳实践。
Lua 脚本在 Redis 中的价值
- 原子性保证:Lua 脚本在 Redis 中以单线程方式执行,执行期间不会被其他命令打断,确保多个命令的原子性(类似事务,但更灵活)。
- 减少网络开销:将多个命令合并为一个脚本,只需一次网络请求,降低延迟(尤其适用于跨机房部署)。
- 复用逻辑:脚本可被缓存,通过摘要(SHA1)重复调用,避免重复传输脚本内容。
Lua 基础:数据类型与语法
Redis 内嵌 Lua 解释器,支持 Lua 5.1 标准语法,核心数据类型如下:
| 类型 | 说明 | 示例 |
|---|---|---|
nil |
空值(未赋值的变量默认为此类型)。 | local a(a 为 nil) |
| 字符串 | 单引号或双引号包裹,支持换行([[ 多行文本 ]])。 |
'hello'、"redis" |
| 数字 | 整数或浮点数(Lua 不区分 int 和 float)。 | 42、3.14 |
| 布尔值 | true 或 false(注意小写)。 |
local flag = true |
| 表(table) | 唯一复合类型,可表示数组、字典或对象(索引从 1 开始)。 | {1, 2, 3} 或 {name = "lua"} |
| 函数 | 支持自定义函数,可作为参数或返回值。 | local f = function(x) return x+1 end |
核心命令:eval 与 evalsha
eval:直接执行脚本
语法:
1 | eval script numkeys key1 [key2 ...] arg1 [arg2 ...] |
script:Lua 脚本字符串。numkeys:后续key参数的数量(必须为整数)。key1...:Redis 键名,在脚本中通过KEYS[1]、KEYS[2]访问(索引从 1 开始)。arg1...:附加参数,在脚本中通过ARGV[1]、ARGV[2]访问。
示例 1:简单脚本
返回键名和参数:
1 | 127.0.0.1:6379> eval "return {KEYS[1], KEYS[2], ARGV[1]}" 2 user:100 post:200 "hello" |