在 Redis Cluster 模式下,使用 EVAL
命令执行 Lua 脚本时,脚本会被分配到哪个节点执行取决于 脚本中操作的键所在的槽(slot)。具体规则如下:
1. 关键规则
- 单键操作:如果脚本只涉及一个键(Key),则根据该键的哈希槽(CRC16 计算)分配到对应的主节点执行。
- 多键操作:如果脚本涉及多个键,则要求这些键必须属于同一个槽(即
hash tag
相同),否则会返回错误CROSSSLOT
。这是 Redis Cluster 对多键操作的强制限制。
2. 哈希标签(Hash Tag)
为了确保多键操作落在同一节点,可以通过 哈希标签 强制将不同的键映射到同一个槽:
- 用
{}
包裹键名的一部分作为计算槽的依据。例如:
这里EVAL "return redis.call('MSET', 'user:{1000}:name', 'Alice', 'user:{1000}:age', 30)" 2 user:{1000}:name user:{1000}:age
{1000}
是哈希标签,两个键会被分配到同一个槽。
3. Lua脚本的执行位置
- 目标节点:脚本最终会在持有相关槽的主节点上执行。
- 客户端重定向:如果客户端连接的节点不是目标节点,Redis 会返回
-MOVED
错误,指示正确的节点地址。智能客户端(如 Jedis、Lettuce)会自动处理重定向。
4. EVALSHA与缓存
EVALSHA
(通过脚本 SHA1 哈希执行)的规则与EVAL
相同,但需先确保目标节点已缓存该脚本(通过SCRIPT LOAD
)。
5. Redis Cluster的限制
- 禁止跨槽操作:若未使用哈希标签且多键属于不同槽,直接报错。
- 原子性局限:即使多键在同一节点,Lua 脚本的原子性仅在该节点生效,不跨节点。
总结
场景 | 分配规则 |
---|---|
单键 | 根据该键的槽分配到对应主节点 |
多键 | 所有键必须属于同一槽(需用 {} 声明哈希标签) |
建议在集群环境下使用 Lua 脚本时显式指定哈希标签以确保正确路由。
内容由零声教学AI助手提供,问题来源于学员提问