我们有一个mongoosejs客户端,可以查询大型mongodb集合(大约1000万条记录)并管道转换为转换流。当我们运行此代码时,节点进程占用100%CPU并变得繁忙,表明背压增加。如果我们周期性地强制读取流的pause(),例如,每100条记录,持续10毫秒,则CPU不会那么繁忙。
据我所知,流API应该检测“背压”问题并在没有开发人员调用pause()和resume()的情况下处理它们。为什么CPU变得如此忙于这个代码,开发像这样的管道的最佳实践是什么?
var Transform = require('stream').Transform;
var util = require('util');
var zlib = require("zlib");
var Model = mongoose.model("xxx", someSchema)
var TransformStream = function() {
return Transform.call(this, {
objectMode: true
});
};
util.inherits(TransformStream, Transform);
var transformChunk = function(chunk){
//return transformed chunk here
}
TransformStream.prototype._transform = function(chunk, encoding, callback) {
var transformed = transformChunk(chunk);
this.push(transformed, "utf-8");
callback();
}
function main(){
var zipStream = zlib.createGzip();
var transformer = new TransformStream();
var queryStream = Model.find(filter).stream();
// outstream is a grid fs stream
return queryStream.pipe(transformer).pipe(zipStream).pipe(outstream);
}
答案 0 :(得分:0)
Backpressure可能会导致您的变换方法被阻止。如果可读流(mongo)正在足够快地生成数据,并且流出存储足够快,那么如果变换器正在执行任何重要操作,则CPU利用率将会很高。您的延迟会限制变压器,从而降低CPU负载。
在文档中并不清楚push
的返回结果有什么相关性,它可能被忽略(但是如果来自下游的背压,这可能会消耗内存)。
我发现你的问题是我自己寻求答案的结果!