node.js : async.each 异步处理大量元素时速度太慢
node.js : async.each gets too slow with large number of elements to process asynchronously
我有一个 4GB RAM 的系统。我需要按以下方式处理一组 200 个文件(平均文件大小 = 20MB):
- 从 gridfs 读取每个文件
- 从文件中提取一些信息
- 将信息存储到 mongoDB
中的某个集合
现在的代码,做同样的事情是:
async.each(files, function (file, callback){
console.log("reading file", file._id);
readstream[file._id] = db.gfs().createReadStream({
_id: file._id
});
readstream[file._id].on('data', function (chunk) {
part[file._id] = part[file._id] && (part[file._id] + chunk.toString()) || chunk.toString();
});
readstream[file._id].on('end', function(){
// do something here
});
}, function (err){
if(err){
console.error("error ", err);
res.json(err);
}
else{
console.log("saved all files ############ YIPPIEEEEEEEEEEEEE ###################");
res.json({"status": 1});
}
});
它对 10 个文件很有用。当文件数量很大(在我的例子中是 200 个)时,它会变得非常慢,可能是由于内存限制。
现在,我一次可以处理 10 个文件,并且可以忍受它,因为它是一次性的 activity。但我想知道在生产中处理此类情况的标准做法是什么?
问题出在并行执行上,因为 async.each
并行执行所有任务,作为解决方法,您可以使用 async.eachSeries to execute the tasks one by one, you may also consider using async.cargo 将多个任务的执行合并到一个镜头中。
您也可以使用 async.eachLimit。
limit
这里是一次最大的异步操作数。这将限制异步
至 运行 N 个并行任务。
异步文档:
The same as each but runs a maximum of limit async operations at a
time.
示例(未测试但这是一次处理 10 个文件的想法):
filesContent = []
async.eachLimit(fileNamesArray, 10, function(fileName, callback) {
// Process a file
processFile(fileName, (err, content) => {
filesContent.push(content);
callback(err);
});
}, function(err) {
// if any of tasks produced an error, err would equal that error
if( err ) {
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
我有一个 4GB RAM 的系统。我需要按以下方式处理一组 200 个文件(平均文件大小 = 20MB):
- 从 gridfs 读取每个文件
- 从文件中提取一些信息
- 将信息存储到 mongoDB 中的某个集合
现在的代码,做同样的事情是:
async.each(files, function (file, callback){
console.log("reading file", file._id);
readstream[file._id] = db.gfs().createReadStream({
_id: file._id
});
readstream[file._id].on('data', function (chunk) {
part[file._id] = part[file._id] && (part[file._id] + chunk.toString()) || chunk.toString();
});
readstream[file._id].on('end', function(){
// do something here
});
}, function (err){
if(err){
console.error("error ", err);
res.json(err);
}
else{
console.log("saved all files ############ YIPPIEEEEEEEEEEEEE ###################");
res.json({"status": 1});
}
});
它对 10 个文件很有用。当文件数量很大(在我的例子中是 200 个)时,它会变得非常慢,可能是由于内存限制。
现在,我一次可以处理 10 个文件,并且可以忍受它,因为它是一次性的 activity。但我想知道在生产中处理此类情况的标准做法是什么?
问题出在并行执行上,因为 async.each
并行执行所有任务,作为解决方法,您可以使用 async.eachSeries to execute the tasks one by one, you may also consider using async.cargo 将多个任务的执行合并到一个镜头中。
您也可以使用 async.eachLimit。
limit
这里是一次最大的异步操作数。这将限制异步
至 运行 N 个并行任务。
异步文档:
The same as each but runs a maximum of limit async operations at a time.
示例(未测试但这是一次处理 10 个文件的想法):
filesContent = []
async.eachLimit(fileNamesArray, 10, function(fileName, callback) {
// Process a file
processFile(fileName, (err, content) => {
filesContent.push(content);
callback(err);
});
}, function(err) {
// if any of tasks produced an error, err would equal that error
if( err ) {
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});