当前位置: 首页 > 面试题库 >

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

呼延博易
2023-03-14
问题内容

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


问题答案:

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

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

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



 类似资料:
  • 我正在开发一个使用Redis的API,它托管在ElastiCache上,有三个节点(一个主节点,两个副本)。周末,由于某种原因,主节点被切换到节点002(从001),这导致我的应用程序在尝试向Redis发送消息时出现只读错误。 有什么理由不手动操作就可以做到这一点?

  • 主要内容:第一个Lua脚本命令,为什么使用Lua脚本,常用脚本命令,基本命令应用从 Redis 2.6 版本开始,Redis 使用内置的 Lua 解释器执行脚本,这意味着我们可以直接在 Redis 客户端执行Lua 脚本 ,于此同时 Redis 还非常贴心地提供了用于编写 Lua 脚本的 命令。 第一个Lua脚本命令 Lua 是一种轻量小巧、开源的脚本语言,用标准 C语言编写。其设计目的就是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。它被广泛的应用于:游戏开发

  • 问题内容: 我创建了一个redis lua脚本来执行基于关键数据类型的命令: 每次执行时,它都会返回null。请帮助纠正脚本。 问题答案: 对响应的返回形式如下表:(如果类型为字符串,则返回) 因此,为了正确检查,您应该将代码更改为: 其余代码将正常运行。 问题是这样的:TYPE命令是少数几个返回“简单字符串”或“状态” redis答复的命令之一(有关响应类型,请参见redis协议规范)。在red

  • 我的问题是:如果有,比方说20个节点,这是相当乏味和耗时的。有没有一种方法可以像Hadoop那样从某个本地化位置启动Spark?当您从主节点运行Hadoop时,它会远程启动所有从节点。我正在寻找一个这样的解决方案,或者一个可以SSH到节点并启动它们的python脚本。

  • 我有两个MariaDB Galera群集(PROD(服务器A、B和C)和DR(服务器1、2和3)。我有从PROD群集的主组件节点(服务器A)到DR群集的主组件节点(服务器1)的标准复制(主从)配置。每个群集都可以正常地独立于其他群集运行(也就是说,如果对一个节点进行更改,则群集中的所有节点立即复制更改)。 这种配置的目的是允许我将中继日志在从机上的应用延迟一段预定的时间。不幸的是,Mariadb1

  • 使用节点。js集群支持,我希望主进程生成添加到Redis队列的数据项。然后,我想运行多个读取Redis队列的工作进程。当然,只有一个工作进程应该使用从队列中检索到的数据项。 为了让我开始学习,您能建议从节点包支持或原始Redis命令的角度来完成这项工作吗?让我强调一下,消费者是节点中独立的进程。js集群环境,我们可以在其中调整竞争从单个Redis队列读取的工作进程的数量,以调整整体系统性能。