我有一个由多个节点组成的redis集群。我想在单个原子操作中更新3个不同的键。我的Lua脚本就像:
local u1 = redis.call('incrby', KEYS[1], ARGV[1])
local u2 = redis.call('incrby', KEYS[2], ARGV[1])
local u3 = redis.call('incrby', KEYS[3], ARGV[1])
我解雇了它:
EVAL script 3 key1 key2 key3 arg
但我得到了WARN Resp(AppErr CROSSSLOT Keys in request don't hash to the same slot)
。上述操作无法完成,更新将失败。我似乎无法使用单个Lua脚本修改不同节点中的键。但根据文件:
必须在执行之前分析所有Redis命令以确定 命令将在哪些键上运行。为了这是真的 对于EVAL,必须明确传递密钥。这在很多方面很有用, 但特别要确保Redis Cluster可以将您的请求转发给 适当的群集节点。
请注意,此规则不会按顺序强制执行 为用户提供滥用Redis单曲的机会 实例配置,代价是编写不兼容的脚本 使用Redis Cluster。
所以我认为只要遵循密钥传递规则,脚本就应该与redis集群兼容。我想知道这里的问题是什么,我应该怎么做才能在一个脚本中更新所有密钥。
答案 0 :(得分:11)
我担心你误解了这些文件。 (我同意它不是很清楚。)
Redis操作,无论是命令还是Lua脚本,只有在所有密钥位于同一服务器上时才能工作。密钥传递规则的目的是允许群集服务器确定发送脚本的位置,并且如果所有密钥都不是来自同一服务器则会快速失败(这就是您的情况)。
因此,您有责任确保您要操作的所有密钥都位于同一台服务器上。这样做的方法是使用哈希标记来强制密钥散列到同一个槽。有关详细信息,请参阅the documentation。