【发布时间】:2015-10-27 17:15:14
【问题描述】:
我是 node.js 的新手,我想对大文件(通常为 5GB ~ 10GB)执行操作(如读取、写入或存储在数据库中)。
在不影响主线程(UI)的情况下,有哪些可能的方法可以快速完成。我需要实现多线程吗?
我认为由于 I/O 操作是异步的,它永远不会影响主线程。我曾尝试读取一个大文件并将内容写入 HTTP 的 response 对象,如下所示 -
var http = require('http'),
fs = require('fs');
fs.readFile('largefile.txt',function(err,data){
if(err) {
throw err;
}
http.createServer(function(request,response){
response.writeHead(200,{
"Content-Type" : "text/plain"
});
response.end(data);
}).listen(8080);
console.log("server started");
});
largefile.txt 的大小只有 .25GB,运行该程序需要将近 5 分钟。现在实际上,我希望大小为(如前所述)5~10GB,文件类型可以是 .csv,.xls。我该怎么做,请举例说明方法(如果可能的话)。
【问题讨论】:
-
你为什么要尝试通过一个函数调用将整个 5-10GB 文件读入内存?您可能会导致操作系统级别的磁盘交换。呃,这需要一点时间。您需要一种比这更有效的数据处理策略。最佳策略在很大程度上取决于数据是什么、它在磁盘上的格式以及你试图用它做什么——你都没有透露。
-
处理磁盘数据的细节与 node.js 无关。这是一个大型数据集的通用编程问题。您必须更具体地了解数据是什么以及您要如何处理这些数据。例如,如果您想将多行 CSV 格式的信息放入数据库,那么您应该一次读取一行,解析它,将其写入数据库,获取下一行等等。有流对象可以为您逐行处理数据。有些数据库具有用于存储数据的接口。
-
而且,是的,如果是 10GB 的数据,那么在任何编程环境中,读取这么大的 CSV 文件并将每一行写入数据库都将花费大量时间。如果都是异步 I/O,那么您的节点服务器可以交错执行其他操作,但编写一个独立的 node.js 程序可能更容易,您可以将其作为子进程启动以使用您的大数据文件并将其放入在数据库中。这样你就有多个 CPU 工作,你的主服务器线程受到的影响就会更小。
-
Node.js 非阻塞并不意味着您不会占用主线程的处理时间。 Node.js 是单线程的,所以异步操作默认是线程安全的,因为只有一个线程。但是,在同一线程上运行的每个异步操作仍然可以轮到并分配时间在该轮次中工作,因此长时间运行的异步操作将占用其他尝试完成自己工作的操作。将繁重的工作委托给专用线程(在这种情况下是另一个 node.js 进程)是通常的解决方案。
-
这个问题中的信息确实仍然不足,无法给出有意义的答案。选择读取巨型文件并将其放入数据库的策略取决于文件中的数据类型、您对数据执行的操作、正在使用的数据库、需要执行的频率、其余部分的繁忙程度您的服务器进程是等等......处理任何语言的大型数据文件是一项特殊的专业知识,无法在 StackOverflow 上的一个答案中完全解释。
标签: node.js multithreading io