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

J F*_*ird 4 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])
Run Code Online (Sandbox Code Playgroud)

我解雇了它:

EVAL script 3 key1 key2 key3 arg
Run Code Online (Sandbox Code Playgroud)

但是我得到了WARN Resp(AppErr CROSSSLOT Keys in request don't hash to the same slot).上述操作无法完成,更新将失败.我似乎无法使用单个Lua脚本修改不同节点中的键.但根据文件:

必须在执行前分析所有Redis命令,以确定命令将在哪些键上运行.为了使EVAL成为现实,必须明确传递密钥.这在许多方面都很有用,但尤其要确保Redis Cluster可以将您的请求转发到适当的群集节点.

请注意,此规则未强制执行,以便为用户提供滥用Redis单实例配置的机会,但代价是编写与Redis Cluster不兼容的脚本.

所以我认为只要遵循密钥传递规则,脚本就应该与redis集群兼容.我想知道这里的问题是什么,我应该怎么做才能更新单个脚本中的所有键.

Kev*_*nry 11

我担心你误解了文档.(我同意这不是很清楚.)

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

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