一尘不染

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

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集群兼容。我想知道这里有什么问题,应该怎么做才能在一个脚本中更新所有键。


阅读 1269

收藏
2020-06-20

共1个答案

一尘不染

恐怕您误解了文档。(我同意这不是很清楚。)

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

因此,您有责任确保要操作的所有密钥都位于同一服务器上。做到这一点的方法是使用 哈希标签
将密钥强制哈希到同一插槽。有关更多详细信息,请参见文档

2020-06-20