[英]Post 1 million object to Mongo DB without running out of memory
為了簡單起見,我在這里使用了一個 for 循環來創建一個包含 100 萬個對象的數組。
我想將數組中的每個對象發布到 mongo db。
我總是內存不足。
我知道我可以增加內存分配,但這不是我想要的解決方案。 由於超出本示例范圍的原因,我也不想使用 mongo 的批量方法。
我知道必須有一些發布這些對象的方法,這意味着每次迭代都會釋放內存(垃圾收集?) - 誰能告訴我它是什么?
謝謝!
當前代碼在這里供參考(導致分配錯誤):
var results = [];
for(var i = 1; i < 1000001; i++){
results.push({"num":i});
}
async = require("async");
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
var mongoUrl = 'mongodb://root@localhost:27017/results';
MongoClient.connect(mongoUrl, function (err, db) {
var collection = db.collection('results');
// 1st para in async.each() is the array of items
async.each(results,
// 2nd param is the function that each item is passed to
function(item, callback){
// Call an asynchronous function, often a save() to DB
collection.insert(item, function (err, result) {
if(err) console.log(err);
console.log(item);
callback();
});
},
// 3rd param is the function to call when everything's done
function(err){
// All tasks are done now
db.close();
}
);
});
async.each()
並行運行插入,因此它基本上啟動了 1000000 個並發插入操作。
您可能希望通過使用async.eachLimit()
將其限制為 100
如果要優化插入,請考慮使用批量操作,因為它還可以減少來回的網絡使用。 還存儲巨大的數組,特別是如果它們只是被計算的話,會消耗太多的內存。
var bulk = collection.initializeUnorderedBulkOp();
var count = 1, i = 0;
var bulkSize = 1000;
var generator = function (mx) {
if(i < mx){
return {num: i++}
}
return null;
}
var run = function () {
doc = generator();
if(doc) {
bulk.insert(doc)
}
if(doc == null || count % bulkSize == 0) {
bulk.execute(function (err, res) {
if(err) {} // do something
if(doc == null) {
db.close
}
run();
})
}
}
run()
在這里,程序的任何步驟都沒有存儲大數組。 只有在創建大容量數組時,您才會存儲它。 一旦達到bulkSize
,它也會被刷新到MongoDB
使用 setImmediate 防止內存不足錯誤
var results = [];
for(var i = 1; i < 1000001; i++){
results.push({"num":i});
}
run(0, results.length, results, function(err){
// do stg
});
function run(done, todo, results, callback)
{
if(++done >= todo)
{
// return callback if all done
return callback(null);
}
else
{
// save one using index
//collection.insert(results[done], function(err, res){
// OR save one and remove it from results
collection.insert(results.splice(0,1),
if(err)
return callback(err);
else
{
// use setImmediate to recall run while releasing stack
return setImmediate(run, ++done, todo, results, callback);
}
});
}
}
老問題,但我在嘗試做類似的事情時遇到了這個問題。 在嘗試插入大約 400 萬份文檔時,我的內存一直在用完。 我的解決方案是將所有數據轉儲到 JSON 文件中,例如:
{ "name", "John", "city": "San Francisco" }
{ "name", "Jane", "city": "New York" }
然后我使用mongoimport
將文件導入 mongo:
mongoimport -u root --authenticationDatabase admin --host="localhost:27017" --db="my_db" --collection="Users" --numInsertionWorkers 4 --file="users.json"
mongoimport
管理內存並有一個很好的輸出顯示(見下文)。 對於 400 萬份文檔,只用了不到 2 分鍾的時間,並且只使用了 900 MB 的 RAM。
2022-06-21T17:46:46.711+0000 [........................] my_db.Users 30.9MB/903MB (3.4%)
2022-06-21T17:46:49.714+0000 [#.......................] my_db.Users 62.2MB/903MB (6.9%)
2022-06-21T17:46:52.711+0000 [##......................] my_db.Users 93.3MB/903MB (10.3%)
2022-06-21T17:46:55.711+0000 [###.....................] my_db.Users 124MB/903MB (13.7%)
2022-06-21T17:46:58.718+0000 [####....................] my_db.Users 155MB/903MB (17.2%)
2022-06-21T17:47:01.711+0000 [####....................] my_db.Users 186MB/903MB (20.6%)
2022-06-21T17:47:04.712+0000 [#####...................] my_db.Users 217MB/903MB (24.0%)
2022-06-21T17:47:07.716+0000 [######..................] my_db.Users 248MB/903MB (27.5%)
2022-06-21T17:47:10.711+0000 [#######.................] my_db.Users 279MB/903MB (30.8%)
2022-06-21T17:47:13.712+0000 [########................] my_db.Users 310MB/903MB (34.3%)
2022-06-21T17:47:16.712+0000 [#########...............] my_db.Users 341MB/903MB (37.7%)
2022-06-21T17:47:19.713+0000 [#########...............] my_db.Users 371MB/903MB (41.0%)
2022-06-21T17:47:22.717+0000 [##########..............] my_db.Users 401MB/903MB (44.4%)
2022-06-21T17:47:25.712+0000 [###########.............] my_db.Users 432MB/903MB (47.9%)
2022-06-21T17:47:28.711+0000 [############............] my_db.Users 464MB/903MB (51.4%)
2022-06-21T17:47:31.712+0000 [#############...........] my_db.Users 495MB/903MB (54.8%)
2022-06-21T17:47:34.713+0000 [#############...........] my_db.Users 526MB/903MB (58.3%)
2022-06-21T17:47:37.711+0000 [##############..........] my_db.Users 557MB/903MB (61.7%)
2022-06-21T17:47:40.713+0000 [###############.........] my_db.Users 588MB/903MB (65.1%)
2022-06-21T17:47:43.712+0000 [################........] my_db.Users 619MB/903MB (68.6%)
2022-06-21T17:47:46.711+0000 [#################.......] my_db.Users 650MB/903MB (71.9%)
2022-06-21T17:47:49.713+0000 [##################......] my_db.Users 680MB/903MB (75.3%)
2022-06-21T17:47:52.711+0000 [##################......] my_db.Users 712MB/903MB (78.8%)
2022-06-21T17:47:55.711+0000 [###################.....] my_db.Users 742MB/903MB (82.2%)
2022-06-21T17:47:58.717+0000 [####################....] my_db.Users 766MB/903MB (84.8%)
2022-06-21T17:48:01.715+0000 [####################....] my_db.Users 783MB/903MB (86.7%)
2022-06-21T17:48:04.712+0000 [#####################...] my_db.Users 810MB/903MB (89.7%)
2022-06-21T17:48:07.720+0000 [######################..] my_db.Users 840MB/903MB (93.0%)
2022-06-21T17:48:10.711+0000 [#######################.] my_db.Users 870MB/903MB (96.3%)
2022-06-21T17:48:13.712+0000 [#######################.] my_db.Users 899MB/903MB (99.6%)
2022-06-21T17:48:14.124+0000 [########################] my_db.Users 903MB/903MB (100.0%)
2022-06-21T17:48:14.124+0000 imported 4027382 documents
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.