我有很多数据要插入(SET \ INCR)到redis数据库,所以我正在通过 node.js 寻找pipeline \ mass insertion。
我在node.js中找不到任何好的示例/ API,所以任何帮助都会很棒!
答案 0 :(得分:10)
是的,我必须同意这方面的例子不足,但我设法创建了我批量发送几个插入命令的流。
您应该为redis stream安装模块:
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 module上的node.js中使用 redis stream 几个例子
答案 1 :(得分:5)
在node_redis中,所有命令都是流水线的:
https://github.com/mranney/node_redis/issues/539#issuecomment-32203325
答案 2 :(得分:2)
您也可以查看batch()
。它multi()
速度慢的原因是因为它是交易性的。如果出现故障,则不会执行任何操作。这可能是你想要的,但你可以在这里选择速度。
redis-stream软件包似乎没有使用Redis&#39;质量插入功能因此它也比质量插入Redis&#39;网站继续与redis-cli
讨论。
另一个想法是使用redis-cli并为其提供一个文件来流式传输,这个NPM包可以做到:https://github.com/almeida/redis-mass
不热衷于首先写入磁盘上的文件?这个回购:https://github.com/eugeneiiim/node-redis-pipe/blob/master/example.js
...也流向Redis,但没有写入文件。它会流式传输到一个生成的进程并经常刷新缓冲区。
On Redis&#39;在质量插入(http://redis.io/topics/mass-insert)下的网站,你可以看到一个小例子。上面的repo基本上将它移植到Node.js,然后直接将它流式传输到生成的redis-cli
进程。
所以在Node.js中,我们有:
var redisPipe = spawn('redis-cli', ['--pipe']);
spawn()
返回对您可以使用stdin
进行管道处理的子进程的引用。例如:redisPipe.stdin.write()
。
您可以继续写入缓冲区,将其传输到子进程,然后每隔一段时间清除一次。然后这不会填补它,因此在内存方面可能会比node_redis
软件包(在其文档中字面上说数据保存在内存中)更好一点,尽管我还没看好深入了解它,所以我不知道内存占用最终会是什么。它可能会做同样的事情。
当然要记住,如果出现问题,一切都会失败。这就像为流利者创建的那些工具(以及另一种选择:http://www.fluentd.org/plugins/all - 它有几个Redis插件)......但同样,这意味着你要支持数据在某种程度上在某个地方的磁盘上。我个人也使用Embulk这样做(这需要磁盘上的文件),但它不支持大量插入,所以它很慢。 30,000条记录耗时近2小时。
流式方法(不受磁盘支持)的一个好处是,如果您正在从另一个数据源执行大量插入操作。假设数据源返回大量数据而您的服务器没有硬盘空间来支持所有数据 - 您可以改为流式传输它。再次,你冒险失败。
我发现自己处于这个位置,因为我正在构建一个Docker镜像,该镜像将在没有足够磁盘空间的服务器上运行以容纳大型数据集。当然,如果你能把所有东西放在服务器的硬盘上,那就容易多了......但是如果你不能,那么流式传输到redis-cli
可能是你唯一的选择。
如果你真的定期推送大量数据,我可能会建议说得流利。它具有许多强大的功能,可确保您的数据能够将其发送到正常运行的位置,如果出现故障,可以恢复。
所有这些Node.js方法的一个问题是,如果某些内容失败,您要么全部丢失,要么必须重新插入。
答案 3 :(得分:0)
默认情况下,node_redis,Node.js库在管道中发送命令,并自动选择每个管道[[https://github.com/NodeRedis/node-redis/issues/539#issuecomment-32203325)][1]中将有多少命令。因此,您不必为此担心。默认情况下,其他Redis客户端可能不使用管道;您需要查看客户端文档以了解如何利用管道。