nodejs耗尽内存处理csv文件

时间:2016-04-08 05:35:32

标签: javascript node.js out-of-memory

我已经阅读了一些关于nodejs内存不足的SO问题,但我没有看到任何听起来与我的情况相似的内容。

我正在尝试处理250个csv文件中的大约20GB的数据(所以~80MB /文件)。使用节点v5.9.1在具有90GB可用内存的服务器上使用--max-old-space-size=8192启动节点脚本。处理完9分钟后,脚本退出并出现内存不足错误。

我是Node编程的新手,但我认为我编写的脚本一次只处理一行数据而不是将任何内容保存在内存中。然而似乎某些对象引用被某些东西所持有,因此脚本正在泄漏内存。这是完整的脚本:

var fs = require('fs');
var readline = require('readline');
var mongoose = require('mongoose');

mongoose.connect('mongodb://buzzard/xtra');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));

var DeviceSchema = mongoose.Schema({
    _id: String,
    serial: String
});

var Device = mongoose.model('Device', DeviceSchema, 'devices');

function processLine(line) {
    var serial = line.split(',')[8];

    Device({
        _id: serial,
        serial: serial
    }).save(function (err) {
        if (err) return console.error(err);
    });
}

function processFile(baseDir, fileName) {
    if(!fileName.startsWith('qcx3'))
        return;

    var fullPath = `${baseDir}/${fileName}`;

    var lineReader = readline.createInterface({
      input: fs.createReadStream(fullPath)
    });

    lineReader.on('line', processLine);
}

function findFiles(rootDir) {
  fs.readdir(rootDir, function (error, files) {
    if (error) {
        console.log(`Error: ${error}` );
        return
    }

    files.forEach(function (file) {
        if(file.startsWith('.'))
            return;

        var fullPath = `${rootDir}/${file}`;

        fs.stat(fullPath, function(error, stat) {
            if (error) {
                console.log(`Error: ${error}` );
                return;
            }

            if(stat.isDirectory())
                dir(fullPath);
            else
                processFile(rootDir, file);
        });
    });
  })
}  


findFiles('c://temp/logs/compress');

我还注意到,当我在一个小得多的测试集上运行脚本,它可以完全完成处理时,脚本最后不会退出。只是一直挂在那里,直到我ctrl + c它。这可能与某种程度有关吗?

我做错了什么?

1 个答案:

答案 0 :(得分:0)

  1. 脚本没有退出,因为你有一个与mongoose的开放连接,在处理了所有文件之后你应该关闭连接并且脚本将完成。
  2. 你有正确的使用流的想法,但我认为你错过了一些东西,我建议你下面的文章来更新streamInterface和事件。 https://coderwall.com/p/ohjerg/read-large-text-files-in-nodejs

  3. 另一个问题来源可能是mongodb,看起来你做了很多插入,它可能与mongodb的最大i / o有关,耗尽了记忆。