nodeJS - 巨大的字符串文件故障

时间:2016-02-13 18:37:34

标签: node.js

我在nodeJS代码中遇到了非常奇怪的问题。代码基本上是将JSON对象序列化为相对较大但不是很大的文件--~150mb。问题是,当我尝试加载此文件时,确实发生了非确定性的事情:

lapsio@linux-qzuq /d/g/GreenStorage> node
> k1=fs.readFileSync('../etc/md5index/green-Documents.extindex');0
0
> k1.length
157839101
> k2=fs.readFileSync('../etc/md5index/green-Documents.extindex');0
0
> k2.lengFATAL ERROR: invalid array length Allocation failed - process out of memory
fish: “node” terminated by signal SIGABRT (Abort)

第二次尝试

> k1=fs.readFileSync('../etc/md5index/green-Documents.extindex');0
0
> k2=fs.readFileSync('../etc/md5index/green-Documents.extindex');0
0
> k1.length
157839101
> k2.length
157839101
> k1==k2
false

在此步骤中,Ofc文件已经缓存在RAM中,从响应时间开始判断,因此不存在存储问题。 我的实际应用:

try{
  var ind = JSON.parse(args.legacyconvert?bfile:content),
      ostr = String(args.legacyconvert?bfile:content),
      str = JSON.stringify(ind,null,2);

  for (var i = 0, l = str.length ; i < l ; i++)
    if (str[i]!=ostr[i]){
      console.error('Soft bug occured - it\'s serious bug and probably classifies as node bug or linux memcache bug. Should be reported');
      throw ('Original string and reparsed don\'t match at '+i+' byte - system string conversion malfunction - abtorting')
    }

  return ind;
} catch (e) {
  console.error('Could not read index - aborting',p,e);
  process.exit(11);
}

结果:

lapsio@linux-qzuq /d/g/G/D/c/fsmonitor> sudo ./reload.js -e ../../../../etc/md5index/*.extindex
Reading index... ( ../../../../etc/md5index/green-Documents.extindex )
Soft bug occured - it's serious bug and probably classifies as node bug or linux memcache bug. Should be reported
Could not read index - aborting ../../../../etc/md5index/green-Documents.extindex Original string and reparsed don't match at 116655242 byte - system string conversion malfunction - abtorting
lapsio@linux-qzuq /d/g/G/D/c/fsmonitor> sudo ./reload.js -e ../../../../etc/md5index/*.extindex
Reading index... ( ../../../../etc/md5index/green-Documents.extindex )
Soft bug occured - it's serious bug and probably classifies as node bug or linux memcache bug. Should be reported
Could not read index - aborting ../../../../etc/md5index/green-Documents.extindex Original string and reparsed don't match at 39584906 byte - system string conversion malfunction - abtorting

每次都会返回随机字节不匹配。此外,保存后文件损坏的可能性为50%。有时它甚至没有正确解析,因为它找到了一些奇怪的非ASCII字符,如[SyntaxError: Unexpected token 䀠]。它是OpenSUSE repo的节点。我试过很多机器。重现这个bug相对比较困难,因为它很随机地发生,但是一旦它第一次出现,它会或多或少地一直显示,直到重新启动。

lapsio@linux-qzuq /d/g/GreenStorage> node -v
v0.12.7

PC有16 GB的内存,节点甚至没有达到10%,所以我确信它并不缺乏内存问题。它似乎与文件系统无关,因为md5sum和其他哈希生成器总是返回有效的校验和。只有节点失败。我不知道该怎么想。它是否真的被归类为bug?

2 个答案:

答案 0 :(得分:2)

您的代码显示您正在啜饮大型JSON文件然后解析它。这意味着你需要为原始文件和生成的解析对象提供空间。对于你不可预测的内存耗尽问题,这可能是部分原因。

大多数使用您提到的文件大小的人都尝试使用流式或增量式解析方法。这样原始数据就会流经你的程序,而不必同时存在。

您可能想要查看此流式JSON解析器。它可能允许您成功地通过这一大块数据。 https://github.com/dominictarr/JSONStream

第二种可能性是(ab-)将第二个参数用于VariableA = MyFunc( """ & var & """ ) 。称为JSON.parse(),它是一个用JSON文本文件中找到的每个对象调用的函数。您可以通过某种方式将对象写入文件(或可能是dbms),然后返回null结果来响应对该函数的每次调用。这样,JSON.parse就不需要存储它遇到的每个对象。你将不得不乱用它来使它正常工作。使用这种策略,你仍然会啜饮大输入文件,但你会输出输出。

另一种可能性是尽力将单个JSON文档拆分为较小文档的记录序列。 (似乎可以合理地将那个大小的数据集分开。)

答案 1 :(得分:1)

我非常怀疑这是由文件大小引起的。这听起来像加载问题。

请参阅此帖子:Max recommended size of external JSON object in JavaScript

我建议在json上查看SQL,这样可以更好地管理那个大小的数据集。