在 Redis Cluster 模式下,使用 EVAL
执行 Lua 脚本时,脚本会被分配到哪个节点执行以及能否操作多个 Key,完全取决于脚本中涉及的 Key 的哈希槽(Slot)分布。以下是详细规则和注意事项:
1. Lua 脚本的执行节点分配规则
单 Key 操作
如果脚本只操作 一个 Key,Redis Cluster 会根据该 Key 的 Slot(通过CRC16(key) % 16384
计算)路由到对应的主节点执行。多 Key 操作
如果脚本操作 多个 Key,则必须满足以下条件之一:- 所有 Key 属于同一个 Slot:通过
{}
定义哈希标签(Hash Tag),强制让多个 Key 映射到同一 Slot。
-- 示例:强制将 key1、key2 分配到 {1000} 的 Slot EVAL "redis.call('SET', 'key1:{1000}', 'val1'); redis.call('SET', 'key2:{1000}', 'val2')" 2 key1:{1000} key2:{1000}
- 否则直接报错:若未用哈希标签且多 Key 属于不同 Slot,Redis Cluster会返回错误:
-ERR CROSSSLOT Keys in request don't hash to the same slot
- 所有 Key 属于同一个 Slot:通过
2. Redis Cluster对多Key操作的严格限制
- 原子性局限:即使多 Key在同一节点(同一Slot),Lua脚本的原子性也仅在该节点生效,无法跨节点保证事务。
- 性能影响:若多Key集中在同一节点,可能引发热点问题。
3. EVALSHA与脚本缓存
EVALSHA
(通过SHA1哈希执行脚本)的规则与EVAL
一致,但需提前在所有相关节点加载脚本(通过SCRIPT LOAD
)。
4.最佳实践建议
场景 | 解决方案 |
---|---|
需要操作多个Key | 强制使用哈希标签(如 {user123} )确保同Slot |
避免跨Slot错误 | 在开发阶段预先检查Key的Slot分布 |
提升性能 | 分散热点Key或使用本地缓存减少Lua依赖 |
总结回答你的问题
- 分配到哪个节点? → 由第一个Key的Slot决定(若多Key需同Slot)。
- 能操作多个Key吗? → 可以,但必须保证这些Key属于同一Slot(用
{}
)。
内容由零声教学AI助手提供,问题来源于学员提问