2016-04-08 50 views
3

recent SO question中,我概述了在处理大量每个包含数百万条记录的csv文件时遇到的OOM条件。事件队列中的节流事件

我越看到这个问题,越是在Node.js上阅读,越是确信OOM不会因为内存泄漏而发生,但是因为我没有限制数据输入到系统中。

该代码只是盲目地吸收所有数据,为每一行创建一个回调事件。事件不断增加到主事件循环中,最终变得非常大以至于耗尽所有可用内存。

什么是Node处理这种情况的惯用模式?我是否应该将csv文件读取到某种阻塞队列中,一旦阻塞队列,阻塞文件读取器解析更多数据?处理大型数据集有没有好的例子?


更新:要快于它可以处理不同的输出把这个更简单,节点可以处理输入和松弛被存储在存储器中(排队作为事件队列事件)。因为有很多松弛,内存最终会耗尽。所以问题是:将输入限制为输出速率的惯用方法是什么?

+0

如果我的答案没有提供足够的细节,那么共享一些示例代码可以帮助我做一个更具体的示例。 – Paul

+0

代码链接在第一句话中。谢谢。 –

+0

我的错误是,我习惯于在被问到的问题中看到相关的代码。我会尽快更新我的答案。 – Paul

回答

1

最好的办法是把事情设置为流,并依靠内置的背压语义来实现。 Streams Handbook作为一个非常好的概述。

与unix类似,节点流模块的主要组合操作符称为.pipe(),并且您可以获得一个免费的背压机制来为缓慢的使用者节流写入。

更新

我没有用比以前的终端输入其他任何内容readline模块,但阅读文档,它看起来像它接受一个输入流和输出流。如果您将数据库写入器构建为可写入数据流,则应该可以让readline在内部为您提供管道。

+0

啊!事情已经开始为我点击了......我使用流来读取数据,但我没有使用管道。 –

+1

最终,我将从readline切换到[node-csv](https://github.com/wdavidw/node-csv),它实现了流。另一方面,我发现至少有一些库([mongoose-object-stream](https://tonicdev.com/npm/mongoose-object-stream)和[mongoose-write-stream](https) ://www.npmjs.com/package/mongoose-write-stream)),它在Mongoose之上实现可写的流。感谢您让我朝着正确的方向前进。 –