为什么我的 Redis Lua 脚本不能自动更新不同 Redis 集群节点上的密钥?

Why can't my Redis Lua script atomically update keys on different Redis Cluster nodes?

我有一个由多个节点组成的 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 脚本修改不同节点中的键。但根据文档:

All Redis commands must be analyzed before execution to determine which keys the command will operate on. In order for this to be true for EVAL, keys must be passed explicitly. This is useful in many ways, but especially to make sure Redis Cluster can forward your request to the appropriate cluster node.

Note this rule is not enforced in order to provide the user with opportunities to abuse the Redis single instance configuration, at the cost of writing scripts not compatible with Redis Cluster.

所以我觉得只要遵循key passing rule,脚本应该是兼容Redis Cluster的。我想知道这里有什么问题,我应该如何更新单个脚本中的所有密钥。

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

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

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