node.js : async.each 异步处理大量元素时速度太慢

node.js : async.each gets too slow with large number of elements to process asynchronously

我有一个 4GB RAM 的系统。我需要按以下方式处理一组 200 个文件(平均文件大小 = 20MB):

现在的代码,做同样的事情是:

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.eachLimitlimit 这里是一次最大的异步操作数。这将限制异步 至 运行 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');
    }
});