8

我有一个由多个节点组成的 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 成为 true,必须显式传递键。这在很多方面都很有用,尤其是确保 Redis 集群可以将您的请求转发到适当的集群节点。

请注意,此规则不是为了给用户提供滥用 Redis 单实例配置的机会而强制执行的,其代价是编写与 Redis 集群不兼容的脚本。

所以我认为只要遵循key传递规则,脚本应该兼容Redis Cluster。我想知道这里有什么问题,我应该怎么做才能更新单个脚本中的所有键。

4

1 回答 1

20

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

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

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

于 2016-07-11T10:33:57.463 回答