在 Redis Lua 脚本中,KEYS
和 ARGV
是传递给脚本的参数数组,它们的区别如下:
KEYS
: 用于传递 Redis 的键(Key),这些键会被 Redis 标记为“已使用”,以确保在集群模式下脚本能正确路由。
ARGV
: 用于传递普通参数(非键名),比如值、标志位等。
你的代码分析
Lua 脚本部分
script = [[
redis.pcall("ZREM", KEYS[1], ARGV[6]) -- KEYS[1] 和 ARGV[6]
redis.pcall("ZREM", ARGV[1], ARGV[6]) -- ARGV[1] 和 ARGV[6]
...
return 0
]]
调用部分
res, err = red_api:eval(
script,
1, -- KEYS 的数量(这里是1个)
KEYS[1], KEYS[2], ..., sid -- 实际参数列表
)
参数映射关系
假设调用时传入的参数顺序如下:
red_api:eval(script,
1, -- KEYS的数量为1
"zset_key", "key2", "key3", "key4", "key5", "key6", "member_id"
)
则参数对应关系为:
Lua脚本中的变量 | 实际传入的值 | 说明 |
---|---|---|
KEYS[1] |
"zset_key" |
(因为 KEYS 数量设为1) |
ARGV[1] |
"key2" |
|
ARGV[2] |
"key3" |
|
ARGV[3] |
"key4" |
|
ARGV[4] |
"key5" |
|
ARGV[5] |
"key6" |
|
ARGV[6] |
"member_id" |
ZREM操作的目标成员 |
关键点
**为什么第一个是
KEYS[1]
,后面是ARGV[...]
:- Redis规定前 N 个参数属于
KEYS
,其余属于 。这里N=1(由第二个参数指定)。
- Redis规定前 N 个参数属于
错误风险:
- 如果实际传入的 KEY数量不足,会报错:
ERR wrong number of arguments for 'eval' command
- 如果实际传入的 KEY数量不足,会报错:
优化建议:
- 明确区分:将真正的Redis键放在 ,其他辅助参数放。
- 动态删除:若需批量删除多个ZSET中的成员,可以循环处理:
local member = ARGV[#ARGV]
for i = 1, #KEYS do
redis.call("ZREM", KEYS[i], member)
end
修正后的调用示例
-- Lua脚本(动态删除所有KEYS中的成员)
local script = [[
local member = ARGV[#ARGV]
for i = #KEYS do
redis.pcall("ZREM", KEYS[i], member)
end
]]
-- 调用(所有键名放到KEY中)
red_api:eval(
script,
6, -- KEY数量=6
"zset_key_abc","zset_key_def","zset_key_ghi",
"zset_key_jkl","zset_key_mno","zset_key_pqr",
"member_id_12345"
)
这样逻辑更清晰且易于维护!
内容由零声教学AI助手提供,问题来源于学员提问