NodeJS – 使用MongoJS Stream的内存/ CPUpipe理

我正在从MongoDBparsing一个相当大的数据集(大约40,000个文档,每个文档都有相当数量的数据)。

stream正在被访问,如下所示:

var cursor = db.domains.find({ html: { $exists: true } }); cursor.on('data', function(rec) { i++; var url = rec.domain; var $ = cheerio.load(rec.html); checkList($, rec, url, i); // This "checkList" function parses HTML data with Cheerio to find different elements on the page. Lots of if/else statements }); cursor.on('end', function(){ console.log("Streamed all objects!"); }) 

每个logging都用Cheerio进行分析(logging包含前面抓取的页面的HTML数据),然后处理Cheerio数据以查找各种select器,然后保存回MongoDB。

对于第一个〜2,000个对象,数据被快速parsing(大约30秒)。 之后,它变得慢得多,大约每秒parsing50条logging。

看看我的MacBook Air的活动监视器,我发现它没有使用大量的内存(226.5mb / 8gb RAM),但它使用了大量的CPU(io.js占用了我CPU的99%)。

这是一个可能的内存泄漏? checkLists函数不是特别密集(至less,据我所知 – 有很多嵌套的if/else statements但没有其他的东西)。

我的意思是清理我的variables后,他们正在使用,如设置$ = ''或类似? 节点的任何其他原因将使用这么多的CPU?

你基本上需要“暂停”stream,否则就“扼杀”它在直接接收到的非常数据项上执行。 所以“事件”中的代码不会在下一个事件被触发之前等待完成,除非您停止事件发射。

  var cursor = db.domains.find({ html: { $exists: true } }); cursor.on('data', function(rec) { cursor.pause(); // stop processessing new events i++; var url = rec.domain; var $ = cheerio.load(rec.html); checkList($, rec, url, i); // if checkList() is synchronous then here cursor.resume(); // start events again }); cursor.on('end', function(){ console.log("Streamed all objects!"); }) 

如果checkList()包含asynchronous方法,则传入游标

  checkList($, rec, url, i,cursor); 

并处理里面的“简历”:

  function checkList(data, rec, url, i, cursor) { somethingAsync(args,function(err,result) { // We're done cursor.resume(); // start events again }) } 

“暂停”停止从stream中发出的事件,直到“resume”被调用。 这意味着您的操作不会在内存中“叠加”,并等待每个操作完成。

你可能想要一些并行处理更高级的stream量控制,但是这基本上是用stream来实现的。 并在里面恢复