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

如何避免Lua脚本限制中的Redis调用?

杜弘光
2023-03-14
问题内容

我正在设置将使用Redis和APCu的PHP标记的缓存实现。由于APC是键值存储,因此我将使用Redis进行键标记关系,并与APC上的每个Web服务器进行同步。

我当前的问题仅涉及Redis。可能您知道实现,但需要明确说明:键可以具有与之关联的标签。在以后的某个时间点,您可以通过某些标签删除缓存的密钥。有很多键,但没有那么多标签,并且键和标签之间存在n对n的关系。

set(key, value, tags) 由组成:

SET key value
foreach tag in tags
    SADD tag key

因为设置后无需检索或更改标签,所以我只需要保持标签与密钥的关系。

deleteByTag(tags)

keys = SUNION tag1 tag2 tag3...
DEL key1 key2 key2...

为了使事情更快,我创建了2个简单的lua脚本,将它们脚本加载并调用EVALSHA。

Lua 设置 脚本:

redis.call('set', KEYS[1], KEYS[2])
for _, tag in pairs(ARGV) do
    redis.call('sadd', tag, KEYS[1])
end

EVALSHA setHash 2 key value tag1 tag2 tag3...

我遇到的 deleteByTag 脚本看起来像这样:

redis.call('del', unpack(redis.call('sunion', unpack(ARGV))))
redis.call('del', unpack(ARGV))

EVALSHA deleteByTagHash 0 tag1 tag2 tag3...

一切都很好,除非redis.call('sunion', unpack(ARGV))返回很多键。看起来Lua对方法可以拥有的参数数量有严格的限制。在我的环境中是8000。
我想知道是否可以通过标签清除键,但要避免:

  • (1)服务器往返,并将密钥来回传递给客户端
  • (2)每个按键上。我尝试使用此修改后的脚本,它比(1)慢

这是(2),运行速度不够快:

for _, key in pairs(redis.call('sunion', unpack(ARGV))) do
    redis.call('del', key)
end
redis.call('del', unpack(ARGV))

问题答案:

我几乎可以肯定,您可以8000通过更改LUAI_MAXCSTACK环境值luaconf.h并重建(Lua环境)来增加该数字()。

正如您已经注意到的,默认值是:

/*
@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
@* can use.
** CHANGE it if you need lots of (Lua) stack space for your C
** functions. This limit is arbitrary; its only purpose is to stop C
** functions to consume unlimited stack space. (must be smaller than
** -LUA_REGISTRYINDEX)
*/
#define LUAI_MAXCSTACK  8000

只是它有点像色情。

如何使用表并遍历table.concat()所有<=8000键呢?



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

  • 问题内容: 以下是我的lua脚本: 如果第一次调用没有退出键,我将不执行第二次调用。 所以…我不知道None的返回值是什么。在python中,返回值将为None。 所以…我该怎么办lua? 使用零时 问题答案: 如果在if语句中使用定义局部变量,则它仅在if语句中存在。在手册中查看局部变量范围。 尝试

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

  • 问题内容: 我试图声明一个没有local关键字的函数,然后从其他脚本调用该函数,但是在运行命令时却给了我一个错误。 编辑: 我不敢相信我仍然没有答案。我将提供我的设置的更多详细信息。 我正在使用带有redis-scripto包的node来将脚本加载到redis中。这是一个例子。 还有lua脚本。 引发以下错误。 问题答案: 重要声明: 请参阅下面的Josiah答案。我的回答原来是 错误的, 或者至

  • 问题内容: 我收集了大约1M个文档。每个文档都有属性,我需要在node.js代码中获取所有。 以前我在用 要么 在Node中。 但是随着集合的增长,我开始出现错误:。 现在,我想使用聚合。它消耗大量内存,速度很慢,但是可以,因为我在脚本启动时只需要执行一次。我在Robo 3T GUI工具中尝试了以下操作: 它有效,我想按以下方式在node.js代码中使用它: 但是在Node中,我收到一个错误:。