【问题标题】:Memory leaks when iterating over mongo data stream using NodeJS使用 NodeJS 迭代 mongo 数据流时内存泄漏
【发布时间】:2015-02-08 03:44:31
【问题描述】:

我正在从 mongodb 集合中流式传输数据,对手头的数据进行一些计算,然后将其存储回 mongo。该过程在前 50k 条左右的记录中运行良好,然后就陷入了困境。前 50k 条记录似乎每秒存储 2-3k 条记录,然后接近每秒 2 条记录。

var stream = Schema.find().stream();
stream.on('data', function (doc) {
  pauseStream(this);
  total++;
  OtherSchema.find().exec(function(err,others) {
   doc.total = others.data + doc.data;
   doc.save(function(err) {
     written++;
   });    
  });
});

function pauseStream(stream) {
  if((total > (written + 50)) && !timedout) {
    timedout = true;
    stream.pause();
    setTimeout(function() {
      timedout = false;
      pauseStream(stream);
    }, 100);
  }
  else {
    stream.resume();
  }
}

我试图将流量控制为一次只有 50 个未完成的更新,我已经上下更改了这个数字,没有改变挂断的位置。我究竟做错了什么?似乎是某种内存泄漏。当我使用 memwatch 时,50k 的统计数据如下所示:

{ num_full_gc: 2368,al: 168610
  num_inc_gc: 55680,
  heap_compactions: 2368,
  usage_trend: 4177.7,
  estimated_base: 89033445,
  current_base: 121087440,
  min: 15957344,
  max: 366396904 }

【问题讨论】:

  • 我想知道使用 setImmediate 是否有帮助 - 在这里查看答案之一stackoverflow.com/questions/16080650/…
  • 这似乎加快了 50k 结果的速度,但结果仍然相同,我想知道是否存在一些关闭/垃圾收集问题。
  • 您好,想看看您是否发现了问题? tnx

标签: javascript node.js mongodb memory-leaks mongoose


【解决方案1】:

我怀疑您的代码中可能存在泄漏。您在内部回调闭包中使用 doc。 保存后尝试告诉 GC doc 不再需要。

OtherSchema.find().exec(function(err,others) {
   doc.total = others.data + doc.data;
   doc.save(function(err) {
     written++;
   });
   doc = null;//tell GC to free doc
  });

【讨论】:

  • 我尝试了很多取消引用的方法来强制 GC 进行清理,但这似乎并不重要。我还读到 GC 应该能够接受这一点。
【解决方案2】:

尝试设置batchSize 而不是自己暂停流。

var stream = Schema.find().batchSize(50).stream();

【讨论】:

  • 这绝对是比我所拥有的更清洁的解决方案,但是在 50k 记录后陷入困境的结果似乎仍然相同。
  • 来自mongodb.github.io/node-mongodb-native/2.0/api/…:batchSize 仅使用针对 MongoDB 服务器的 getMoreCommand 调节每批返回多少文档
猜你喜欢
  • 2012-09-12
  • 2013-11-02
  • 2016-04-22
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
相关资源
最近更新 更多