13

我有很多数据要插入(SET \ INCR)到redis DB,所以我正在寻找管道\通过node.js进行大规模插入

我在 node.js 中找不到任何好的示例/ API,所以任何帮助都会很棒!

4

4 回答 4

11

是的,我必须同意缺乏这方面的示例,但我设法创建了流,我在该流上批量发送了几个插入命令。

您应该为 redis 流安装模块:

npm install redis-stream

这就是您使用流的方式:

var redis = require('redis-stream'),
    client = new redis(6379, '127.0.0.1');

// Open stream
var stream = client.stream();

// Example of setting 10000 records
for(var record = 0; record < 10000; record++) {

    // Command is an array of arguments:
    var command = ['set', 'key' + record, 'value'];  

    // Send command to stream, but parse it before
    stream.redis.write( redis.parse(command) );
}

// Create event when stream is closed
stream.on('close', function () {
    console.log('Completed!');

    // Here you can create stream for reading results or similar
});

// Close the stream after batch insert
stream.end();

此外,您可以根据需要创建任意数量的,并随时打开/关闭它们。

在redis-stream 节点模块上的 node.js 中有几个使用redis 流的例子

于 2014-02-07T16:25:57.843 回答
6

在 node_redis 中,所有命令都是流水线的:

https://github.com/mranney/node_redis/issues/539#issuecomment-32203325

于 2014-02-10T15:26:17.610 回答
2

你可能也想看看batch()。它会变慢的原因multi()是因为它是事务性的。如果某事失败,则不会执行任何操作。这可能是您想要的,但您确实可以在这里选择速度。

redis-stream 包似乎没有使用 Redis 的批量插入功能,因此它也比批量插入 Redis 网站继续谈论的要慢redis-cli

另一个想法是使用 redis-cli 并给它一个文件来流式传输,这个 NPM 包可以做到:https ://github.com/almeida/redis-mass

不热衷于先写入磁盘上的文件?这个回购:https ://github.com/eugeneiiim/node-redis-pipe/blob/master/example.js

...也流到 Redis,但不写入文件。它流向生成的进程并每隔一段时间刷新缓冲区。

在 Redis 的大量插入 ( http://redis.io/topics/mass-insert ) 站点上,您可以看到一个小的 Ruby 示例。上面的 repo 基本上将其移植到 Node.js,然后将其直接流式传输到生成的redis-cli进程。

所以在 Node.js 中,我们有:

var redisPipe = spawn('redis-cli', ['--pipe']);

spawn()返回对子进程的引用,您可以使用stdin. 例如:redisPipe.stdin.write()

您可以继续写入缓冲区,将其流式传输到子进程,然后每隔一段时间清除一次。这不会填满它,因此在内存上可能会比node_redis包好一点(在其文档中字面上说数据保存在内存中)虽然我没有深入研究它所以我没有知道内存占用最终是什么。它可能正在做同样的事情。

当然请记住,如果出现问题,一切都会失败。这就是创建 fluentd 之类的工具的目的(这是另一种选择:http ://www.fluentd.org/plugins/all - 它有几个 Redis 插件)......但同样,这意味着您正在支持磁盘上的数据在某种程度上。我个人也使用 Embulk 来执行此操作(这需要磁盘上的文件),但它不支持批量插入,因此速度很慢。30,000 条记录用了将近 2 个小时。

流式传输方法(不受磁盘支持)的一个好处是,如果您正在从另一个数据源进行大量插入。假设数据源返回大量数据并且您的服务器没有硬盘空间来支持所有数据 - 您可以改为流式传输。同样,你冒着失败的风险。

我发现自己处于这个位置,因为我正在构建一个 Docker 映像,该映像将在没有足够磁盘空间来容纳大型数据集的服务器上运行。当然,如果您可以将所有内容都放在服务器的硬盘上,这会容易得多……但如果您不能,流式传输redis-cli可能是您唯一的选择。

如果你真的定期推送大量数据,老实说,我可能会推荐 fluentd。它具有许多出色的功能,可确保您的数据到达目的地,如果出现故障,它可以恢复。

所有这些 Node.js 方法的一个问题是,如果某件事情失败,您要么全部丢失,要么必须重新插入。

于 2016-05-05T23:43:45.350 回答
0

默认情况下,node_redis,Node.js 库在管道中发送命令,并自动选择有多少命令将进入每个管道 [( https://github.com/NodeRedis/node-redis/issues/539#issuecomment-32203325)] [1]。因此,您无需担心这一点。但是,其他 Redis 客户端可能默认不使用管道;您需要查看客户端文档以了解如何利用管道。

于 2020-05-31T19:40:57.627 回答