在 Redis Lua 脚本中,`keyCount` 参数的作用是**明确区分脚本参数中的 KEYS 和 ARGV**,具体关系如下:
核心作用
- **参数分类标识**
-
`keyCount` 表示脚本中使用的 Redis KEY 的数量(即 `KEYS` 数组的长度)
-
剩余参数自动归类为 `ARGV` 数组(Lua 脚本中的普通参数)
- **执行时自动分组**
当调用 `EVAL` 命令时,Redis 会根据 `keyCount` 将参数列表分割为两部分:
```bash
EVAL "脚本内容" <keyCount> <KEY1> <KEY2>... <ARG1> <ARG2>...
```
参数传递规则
- **`keyCount >= 0`**
自动将前 `keyCount` 个参数视为 `KEYS`,后续参数视为 `ARGV`。
**示例**:
```go
script := NewScript(2, "return {KEYS[1],KEYS[2],ARGV[1]}") // 2个KEY
reply, _ := script.Do(redisClient, "key1", "key2", "arg1")
```
-
`KEYS` = `["key1", "key2"]`
-
`ARGV` = `["arg1"]`
-
**`keyCount < 0`**
需手动在参数列表**第一个位置**指定 KEY 的数量(灵活性更高)。
**示例**:
```go
script := NewScript(-1, "return {KEYS[1],ARGV[1]}") // 动态KEY数量
reply, _ := script.Do(redisClient, 1, "key1", "arg1") // 第一个参数1表示KEY数量
```
-
`KEYS` = `["key1"]`
-
`ARGV` = `["arg1"]`
与 Lua 脚本的关系
在脚本内部通过 `KEYS` 和 `ARGV` 数组访问参数:
```lua
-- 假设 keyCount=2,参数为 ["k1", "k2", "a1"]
local key1 = KEYS[1] -- "k1"
local arg1 = ARGV[1] -- "a1"
```
为什么需要 keyCount?
- **Redis 集群兼容性**
Redis 需要根据 KEY 计算数据所在的节点,明确 KEY 数量可确保集群模式下正确路由。
- **参数安全隔离**
避免 KEY 和普通参数混淆(例如防止误将 ARGV 当作 KEY 操作)。
- **性能优化**
提前声明 KEY 数量可减少运行时参数解析开销。
生产建议
-
**固定 KEY 数量时**:直接指定 `keyCount`(如 `NewScript(2, ...)`)
-
**动态 KEY 数量时**:用 `keyCount=-1` 并在调用时手动传递数量
-
**脚本缓存**:配合 `EVALSHA` 使用(`NewScript` 生成的哈希值用于标识脚本)