在Node中使用lua脚本扫描Redis键

我一直在尝试使用scan获取Redis中的所有键,同时避免使用count。问题在于,当有许多键时(例如1000000),扫描 SCAN 0 MATCH * 比以下方式要慢得多:

KEYS *

SCAN 0 MATCH * COUNT 1000000

我阅读了一篇文章,建议使用Lua以获得更好的性能。有人能帮我处理这个问题吗?我想使用Lua处理超过1M个键的扫描。我正在使用通过npm安装的redis包。

点赞
用户7017466
用户7017466

COUNT 1000000 的情况下使用 SCAN 要比使用 KEYS 略微糟糕。

Redis 是单线程的。引入 SCAN 命令的原因之一是允许在不长时间阻塞服务器的情况下一次前进几步遍历所有的键。

默认值是 10。这意味着该命令会返回大约 10 个键,如果键在哈希槽中稀疏分布或被 MATCH 模式过滤掉,则可能少于 10 个。如果某些键共享一个哈希槽,则可能会返回更多。无论如何,执行的工作量与 COUNT 参数成比例。

这并不意味着 KEYS 命令(或带有大量 COUNT 数字的 SCAN)被禁止使用。如果您可以接受服务器被阻塞的时间,那就使用它吧。

请参阅 Redis 中 SCAN / HSCAN 命令的 COUNT 有没有推荐的值? 了解更多详细信息和一个 Lua 示例。

如何将 Redis 中运行的两个单独的 DB(例如 db0、db1)合并为一个单独的 DB(db0)?如何获取 Redis 中的所有集合? 中,我发布了如何使用 Lua 脚本中的 SCAN 命令实现定制需求的示例。

您可能会觉得 Redic `SCAN`:如何在新键可能匹配并确保结果在合理时间内得出之间保持平衡? 很有趣。

如何在 node.js 中使用 Lua 和 Redis:执行 Redis 中的 eval 命令以在 nodeJS 中运行 Lua 脚本

2020-02-12 16:21:56
用户12882502
用户12882502

发现相关解决方案。请查看此链接

不建议使用键(Keys),如果查看文档,你会发现这一点。尽管这里提供了性能,但仅仅是为了更深入地了解知识,别无其他。最好的方法是使用建议使用Lua脚本,性能确实非常好。如果你看一下评论,也会了解到差异,我想。

TEXTAREA:

  • KEYS:最快的方法
  • SCAN:慢约1.5倍
  • 带有Lua的扫描:慢约2.4倍
  • 带有Lua和额外检查的扫描:慢约4.3倍
  • KEYS与Lua:慢约18倍

对我来说,理解Lua的语法非常困难。因此,这里是代码帮助理解语法。

在Lua脚本中不带计数进行扫描:

local ans, has, cursor = {}, {}, "0";
repeat
    local t = redis.call("SCAN", cursor, "MATCH", KEYS[1], "COUNT", 1000000000);
    local list = t[2];
    for i = 1, #list do
        local s = list[i];
        if has[s] == nil then 
            has[s] = 1; 
            ans[#ans + 1] = s;
        end;
    end;
    cursor = t[1];
until cursor == "0";
return #ans; --或者返回ans;
2020-02-13 06:05:13