【问题标题】:Why can't my Redis Lua script atomically update keys on different Redis Cluster nodes?为什么我的 Redis Lua 脚本不能自动更新不同 Redis Cluster 节点上的键?
【发布时间】:2016-11-09 02:59:54
【问题描述】:

我有一个由多个节点组成的 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 集群。

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

【问题讨论】:

    标签: redis redis-cluster


    【解决方案1】:

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

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

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

    【讨论】:

    • 我明白了。我使用集群的原因是希望不同的键在不同的节点中进行扩展。所以在这种情况下,我可能会放弃以原子方式更新密钥。非常感谢。
    • 也许我有点晚了,但我有一个后续问题:如果我确定一个未指定的密钥在同一个集群上,我还可以使用 Lua 脚本吗?所以我打破了必须指定所有键的规则,但遵循所有键都在同一台服务器上的规则。
    • @user3688217:是的,我相信。只要密钥在同一台服务器上,它就可以工作,即使密钥未声明。
    • 我想mget可以在redis集群的不同节点上获取key?
    猜你喜欢
    • 2013-05-17
    • 2016-08-10
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2022-01-26
    • 2016-05-20
    • 1970-01-01
    相关资源
    最近更新 更多