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

标签 lua redis

我正在设置一个将同时使用 Redis 和 APCu 的 PHP 标记缓存实现。 由于 APC 是键值存储,我将使用 Redis 建立键标签关系并与 APC 上的每个网络服务器同步。

我目前的问题只涉及 Redis。 您可能知道实现方式,但要弄清楚: key 可以具有与之关联的标签。在稍后的某个时间点,您可以通过某些标签删除缓存的 key 。 有很多键,没有那么多标签,键和标签之间存在 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。
我想知道是否有办法通过标签清除 key 但避免:

  • (1) 往返服务器并将 key 来回传输给客户端
  • (2) for-each on keys。我尝试使用这个修改后的脚本,它比 (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 )您环境中的值(value) 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() block <=8000 key ?

关于lua - 如何避免 Lua 脚本限制中的 Redis 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19202367/

相关文章:

lua - 如何向 lua 程序传递和读取参数?

json - 我如何将这些数据正确存储在 redis 中?

redis - 存储数据并同时订购列表的最佳方式

multithreading - node.js 集群中的子进程间通信选项

docker - Redis Docker 未与其他 Docker 容器链接

lua - Lua 中列出对象字段

regex - 纯 Lua 中功能齐全的正则表达式库

amazon-web-services - 通过 Cloudformation 添加新分片时,在错误的可用区中创建只读副本

java - 如何在 Luaj 中加载 Lua-Filesystem 和 Lua-Penlight

c++ - 解决随机崩溃