Redis集群:使用Lua脚本更新不同节点中的密钥

时间:2016-07-06 22:01:07

标签: redis

我有一个由多个节点组成的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集群兼容。我想知道这里的问题是什么,我应该怎么做才能在一个脚本中更新所有密钥。

1 个答案:

答案 0 :(得分:11)

我担心你误解了这些文件。 (我同意它不是很清楚。)

Redis操作,无论是命令还是Lua脚本,只有在所有密钥位于同一服务器上时才能工作。密钥传递规则的目的是允许群集服务器确定发送脚本的位置,并且如果所有密钥都不是来自同一服务器则会快速失败(这就是您的情况)。

因此,您有责任确保您要操作的所有密钥都位于同一台服务器上。这样做的方法是使用哈希标记来强制密钥散列到同一个槽。有关详细信息,请参阅the documentation