NodeJS - Memory/CPU 使用 MongoJS Stream 进行管理
NodeJS - Memory/CPU management with MongoJS Stream
我正在解析来自 MongoDB 的一个相当大的数据集(大约 40,000 个文档,每个文档中都有相当数量的数据)。
正在像这样访问流:
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!");
})
每条记录都用 Cheerio
进行解析(该记录包含 HTML 之前抓取的页面数据),然后我处理 Cheerio 数据以查找各种选择器,然后保存回 MongoDB.
对于前 ~2,000 个对象,数据解析速度非常快(约 30 秒)。之后它变得更慢,每秒解析大约 50 条记录。
查看我的 Macbook Air 的 activity 显示器,我发现它没有使用大量内存(226.5mb / 8gb ram),但它使用了大量 CPU(io.js 占了我的 99% cpu).
这可能是内存泄漏吗? checkLists
函数不是特别密集(或者至少,据我所知 - 有相当多的嵌套 if/else statements
但其他的不多)。
我是否打算在变量使用后清除它们,比如设置 $ = ''
或类似的? Node 的任何其他原因都会使用这么多 CPU?
您基本上需要 "pause" 流,否则 "throttle" 它会在立即收到的数据项上执行。因此 "event" 中的代码不会在触发下一个事件之前等待完成,除非您停止事件发射。
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()
包含异步方法,则传入游标
checkList($, rec, url, i,cursor);
并处理里面的"resume":
function checkList(data, rec, url, i, cursor) {
somethingAsync(args,function(err,result) {
// We're done
cursor.resume(); // start events again
})
}
"pause" 停止从流发出的事件,直到 "resume" 被调用。这意味着您的操作不会 "stack up" 在内存中并等待每个操作完成。
您可能需要对某些并行处理进行更高级的流控制,但这基本上就是您使用流进行处理的方式。
并在里面恢复
我正在解析来自 MongoDB 的一个相当大的数据集(大约 40,000 个文档,每个文档中都有相当数量的数据)。
正在像这样访问流:
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!");
})
每条记录都用 Cheerio
进行解析(该记录包含 HTML 之前抓取的页面数据),然后我处理 Cheerio 数据以查找各种选择器,然后保存回 MongoDB.
对于前 ~2,000 个对象,数据解析速度非常快(约 30 秒)。之后它变得更慢,每秒解析大约 50 条记录。
查看我的 Macbook Air 的 activity 显示器,我发现它没有使用大量内存(226.5mb / 8gb ram),但它使用了大量 CPU(io.js 占了我的 99% cpu).
这可能是内存泄漏吗? checkLists
函数不是特别密集(或者至少,据我所知 - 有相当多的嵌套 if/else statements
但其他的不多)。
我是否打算在变量使用后清除它们,比如设置 $ = ''
或类似的? Node 的任何其他原因都会使用这么多 CPU?
您基本上需要 "pause" 流,否则 "throttle" 它会在立即收到的数据项上执行。因此 "event" 中的代码不会在触发下一个事件之前等待完成,除非您停止事件发射。
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()
包含异步方法,则传入游标
checkList($, rec, url, i,cursor);
并处理里面的"resume":
function checkList(data, rec, url, i, cursor) {
somethingAsync(args,function(err,result) {
// We're done
cursor.resume(); // start events again
})
}
"pause" 停止从流发出的事件,直到 "resume" 被调用。这意味着您的操作不会 "stack up" 在内存中并等待每个操作完成。
您可能需要对某些并行处理进行更高级的流控制,但这基本上就是您使用流进行处理的方式。 并在里面恢复