MongoDB-mongoose high cpu use when saving large documents in node.js -
i'm developing pixel tracking app hosted on ec2, called on every request of video ad, tracks when started, completed , if click action made. i'm using node.js express wanted respond fast possible , mongodb/mongoose since server log structure. receive requests every millisecond. when storing documents collection, takes huge amount of cpu 100% , in end node.js launches error:
get /pixel/impression/ad1 200 1ms fatal error: call_and_retry_2 allocation failed - process out of memory i think it's mongoose operation 1 who's taking of cpu remove parts, never hangs.
on app.js have:
var hostschema = new mongoose.schema({ ip: string, date: { type: date, default: date.now } }); var orderschema = new mongoose.schema({ name: string, metriccount: { impression: { type: number, default: 0 }, clicks: { type: number, default: 0 }, complete: { type: number, default: 0 } }, impressionhosts: [hostschema], clickshosts: [hostschema], completehosts: [hostschema] }); var order = mongoose.model('order', orderschema); var host = mongoose.model('host', hostschema); and the express method:
app.get('/pixel/:metric/:campaignname', function(req, res){ var campaignname = req.params.campaignname; var metrica = req.params.metric; order.find({name: campaignname}, function(err, doc){ newmet = {}; newmet[metrica] = 1; var incominghost = new host({ip: req.ip}); if(doc.length<1){ insertnewelement(campaignname, newmet, metrica, incominghost); }else { updateelement(doc[0], metrica, incominghost); } }); res.end(pixel, 'binary'); }); when comment "updateelement" function, node.js performs "perfectly". here these functions:
function updateelement(doc, metrica, incominghost){ doc.metriccount[metrica]+=1; doc[metrica+'hosts'].push(incominghost); doc.save(function(err){ if(err){ console.log(err); } //console.log('record updated') }); } function insertnewelement(campaignname, newmet, metrica, incominghost) { new order({ name : campaignname, metriccount: newmet }).save(function(err, doc){ if (err) res.json(err); doc[metrica+'hosts'].push(incominghost); doc.save(function(err){ if(err){ console.log(err); } // console.log('new record added '+ doc.name); }); }); } i believe problem resides when pushing new host, since there lot, although, i'm not expert on mongodb don't know how improve method, if that's causing issues. of code has been tweaked mongo documentation , research.
how can make update faster , avoid memory error on nodejs?
thank you!
when create document in mongo, allocates portion of disk space document, enough padding accommodate document estimated growth. if document size exceeds allocated space, mongo needs move , reallocate new space document. keep happening document growing.
to avoid this, need pre-allocate space. filling enough data document mongo allocate enough space fit max document size.
in case, when first insert new document, add enough host sub documents, replicate larger documents. after insert document, can remove hosts sub documents , insert correct records.
now, not perfect. mongo not support transactions, may have update hitting document before insert process cleans pre-allocated document.
also mongo, keep field names short possible. mongo stores full field name part of document whenever used. while may not seem much, can account significant amount of disk space in large collections.
Comments
Post a Comment