我已经阅读了许多有关 NodeJS 内存不足的问题,但我还没有看到任何听起来与我的情况类似的内容。
我正在尝试处理 250 个 csv 文件中约 20GB 的数据(因此每个文件大约 80MB)。使用 Node v5.9.1 在具有 90GB 可用内存的服务器上使用 --max-old-space-size=8192
启动 Node 脚本。处理 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 为止。这可能有某种关联吗?
我做错了什么?
最佳答案
- 脚本未退出,因为您与 Mongoose 有一个打开的连接,处理完所有文件后,您应该关闭连接,脚本将完成。
您对使用流的想法是正确的,但我认为您错过了一些东西,我建议您阅读以下文章来更新流接口(interface)和事件。 https://coderwall.com/p/ohjerg/read-large-text-files-in-nodejs
问题的另一个来源可能是 mongodb,看起来您做了很多插入,这可能与 mongodb 的最大 i/o 耗尽内存有关。
关于javascript - Nodejs处理csv文件内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36492268/