ZBLOG

script = [[ redis.pcall("ZREM", KEYS[1], ARGV[7]) redis.pcall("ZREM", ARGV[1], ARGV[7]) redis.pcall("ZREM", ARGV[2], ARGV[7]) redis.pcall("ZREM", ARGV[3], ARGV[7]) redis.pcall("ZREM", ARGV[4], ARGV[7]) redis.pcall("ZREM", ARGV[5], ARGV[7]) redis.p...

在 Redis Cluster 模式下,Lua 脚本的 执行节点由传入的 KEYS 参数的哈希槽(Slot)决定。具体规则如下:


1. 关键结论

  • 该脚本的执行节点由 KEYS[1] 的 Slot 决定(因为 eval 命令的第3个参数是 1,表示只有 KEYS[1] 被视为路由 Key)。
  • 其他所有参数(包括 ARGV[...] 和其他 KEYS[...])不会影响路由,但必须满足以下条件:
    • 所有被操作的 Key(即 ZREM 的目标 Key)必须与 KEYS[1] 属于同一个 Slot,否则会报错:
      
      -ERR CROSSSLOT Keys in request don't hash to the same slot
      

2. 代码分析

(1) EVAL 命令的参数结构

red_api:eval(
    script,          -- Lua脚本内容
    1,               -- KEY数量(此处为1,表示只有 KEYS[1] 是路由Key)
    KEYS[1],         -- 第一个Key(决定脚本执行节点)
    KEYS[2], ...,    -- 其他Key(需与 KEYS[1]同Slot)
    ARGV[1], ...,    -- ARGV参数(不影响路由)
    sid              -- ARGV[7]
)

(2) Lua脚本中的实际操作

脚本中通过 ZREM 操作了以下 Key:

redis.pcall("ZREM", KEYS[1], ARGV[7])   -- KEYS[1]
redis.pcall("ZREM", ARGV[1], ARGV[7])    -- ARGV[1]
redis.pcall("ZREM", ARGV[2], ARGV[7])    -- ARGV[2]
...
  • 必须确保
    所有被操作的 Key(即 KEYS[1], ARGV[1], ARGV[2], …, ARGV6]) 属于同一个 Slot

3. Hash Tag强制同Slot的方法

如果这些 Key 天然不属于同一 Slot,需要通过 Hash Tag(用花括号标记部分字符串)强制它们映射到同一 Slot。例如:

-- 示例:强制所有Key使用 {user123} 作为Tag
local sid = "user123"
red_api:eval(script, 
    1, 
    "myzset:{user123}",      -- KEYS[1]
    "arg_key1:{user123}",    -- ARGV对应的实际值需替换为带Tag的Key
    "arg_key2:{user123}",
    ...
)

4.错误排查建议

如果遇到跨 Slot错误:

  • 检查所有被操作的 Key:确保它们通过 Hash Tag或自然分布属于同一 Slot。

  • 日志调试:在调用前打印所有 Key,手动计算它们的 Slot:

    # Redis命令行工具计算Slot
    redis-cli -c CLUSTER KEYSLOT "key_name"
    

总结回答你的问题

这段代码中,最终决定脚本执行节点的参数是 `KEYS [1]。其他所有被操作的 Key必须与它属于同一 Slot!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23663

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?