MongoClient.connect(url, function(err, db) {
var batch = db.collection("chatmessage").initializeOrderedBulkOp();
//var batch = db.collection("chatmessage").db.collection.initializeUnorderedBulkOp()
var messageNum=0;
var chatmessage = null;
var count =0;
for (var i = 0;i<300;i++){
messageNum = getMessage();//value from 1~500000;
for(var j = 0;j<messageNum;j++){
count++;
chatmessage = generateChatMessage();
batch.insert(chatmessage);
if(count>=1000){
count=0;
batch.execute(function(err){
console.log(err);
batch = db.collection("chatmessage").initializeOrderedBulkOp();
console.log("batch execute"+util.inspect(process.memoryUsage()));
//db.close();
});
}
}
console.log("execute one chatroom"+util.inspect(process.memoryUsage()));
}
if(count>0){
batch.execute(function(err){
console.log(err);
batch = db.collection("chatmessage").initializeOrderedBulkOp();
});
}
}
需要使用nodejs.使用Bulk方法将数百万条消息填充到mongo中以进行插入批处理。
但是有一些关于代码的问题
批量执行方法运行async。 当插入数据= 100,000时,没有看到任何批量执行完成,直到所有代码完成执行,可以看到打印“批量执行”。
当messageNum的变量很大时,大约50,000.it将内存不足。
致命错误:CALL_AND_RETRY_LAST分配失败 - 处理内存不足
变量都是在循环外部定义的,并且运行了batch.execute。 不明白为什么会发生这种情况。
这与DB有关,当我删除DB操作时,没有问题。 我猜batch.execute()方法占用了这个内存。但是即使使用db.close()也无法释放它。
{rss:1449750528,heapTotal:1091999056,heapUsed:922237384}
------------------------------------------- UPDATE1 --- ---------------------------
使用heapdump包获得了多个heapdump snapshoot文件。
根本原因是batch.execute方法是异步调用。直到所有代码都被执行时才会执行,正如我在第一个问题中提到的那样。【也怀疑即使是batch.execute()也是异步执行的。应该运行独立,不受主进程的影响。但我还没有发现它们写入db,并且回调方法中的信息日志尚未打印出来】 因此,所有需要插入mongo的文档都会留在内存中。导致问题。
@joeytwiddle发现你对这个问题有一个共同的看法。 来自bulk-upsert-in-mongodb
没有发现bulk.execute()方法可以配置sync执行。 任何人都有任何想法来解决这个问题。
答案 0 :(得分:0)
我也遇到了这个错误但是当我使用这个代码时它的工作正常。 简单插入的示例使用Generator和co模块的许多操作。你也可以检查一下;
var MongoClient = require('mongodb').MongoClient,
co = require('co');
test = require('assert');
co(function*() {
var db = yield MongoClient.connect('mongodb://localhost:27017/test');
// Get the collection
var col = db.collection('insert_many_with_generators');
var r = yield col.insertMany([{a:1}, {a:2}]);
test.equal(2, r.insertedCount);
// Finish up test
db.close();
});