【问题标题】:Memory limit exceeded error when reading a large file with node js and readline使用节点 js 和 readline 读取大文件时出现内存限制超出错误
【发布时间】:2018-02-25 11:37:36
【问题描述】:

使用 readline 时出现内存错误。部分代码如下所示:

            var lineReader = require('readline').createInterface({
                input: require('fs').createReadStream('/tmp/temp.ttl')
            });
            let entity;
            let tripleKey;
            let triple;
            console.log('file ready for processing');
            lineReader.on('line', function (line) {
                triple = parser.parse(line)[0];
                if (triple) {
                    tripleKey = datastore.key('triple');
                    entity = prepare_entity(tripleKey, triple);
                    lineReader.pause();
                    datastore.save(entity).then(()=>lineReader.resume());                      
                    number_of_rows += 1;
            };

我认为“在线”事件的所有内存都是预先分配的,因为它在循环之外。所以我的问题是,什么可能导致本节代码中的内存消耗?

作为对 Doug 的回应,将 readline 更改为完全流式传输现在会在 140,000 个实体(而不是之前的 40,000 个)之后显示内存限制错误。

见下文:

const remoteFile = bucket.file(file.name);

var lineReader = require('readline').createInterface({
    input: remoteFile.createReadStream()
});
console.log('file ready for processing');
lineReader.on('line', function (line) { ...

【问题讨论】:

  • 你是如何创建 readline 界面的?
  • 添加了创建linereader界面的sn-p
  • 该文件有多大? prepare_entity 做了什么并返回?什么是datastore(它是内存中的东西)?你怎么知道/怀疑readline 内存不足?我的赌注是datastore.save。旁注:注意let 的点正是它在块级别上的作用域——在块之外预先声明实体、tripleKey 和triple 会破坏这个细节,也会使代码更长。
  • 文件为1.2G。 Datastore 是谷歌云产品。 prepare_entity 提供一个包含三键和三个字符串的字典。

标签: node.js google-cloud-datastore google-cloud-functions readline


【解决方案1】:

在 Cloud Functions 中,/tmp is a memory-based filesystem。这意味着您的 1.2GB 文件实际上占用了 1.2GB 的内存。这是很多内存。

如果您需要更多内存,可以尝试在Cloud Console 中为您的函数增加内存限制,最高可达 2GB。

相反,您可能想尝试从源文件流式传输文件并处理流式传输,而不是在本地下载整个内容。随着时间的推移,您可以通过这种方式节省内存使用量。

【讨论】:

  • 它改善了问题,因为我现在在内存限制错误(2GB)之前获得了 140,000 条记录。现在代码如下:const remoteFile = bucket.file(file.name); const datastore = new Datastore({}); let number_of_rows = 0; var lineReader = require('readline').createInterface({ input: remoteFile.createReadStream() }); console.log('file ready for processing'); lineReader.on('line', function (line) { let triple = parser.parse(line)[0]; if (triple) { ...
  • 如果您更新了代码,请将其添加到您的问题中。真的很难在评论中阅读。
猜你喜欢
  • 2018-10-13
  • 2020-07-26
  • 2023-02-17
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 2020-02-18
相关资源
最近更新 更多