Using MongoDB's findOneAndUpdate with Replica Set Awareness to Reduce Load on Primary DB
I’ll introduce how I reduced database load by being aware of MongoDB’s replica set and combining Mongoose’s findOneAndUpdate and findOne to prevent too many queries from being sent to the Primary DB.
findOneAndUpdate always sends queries to the Primary DB.
So, even for processes like the following where you only create a document on the first time but subsequent times could be handled with just findOne, queries are sent to the Primary DB, preventing effective use of Secondary DBs.
WishListConfig.findOneAndUpdate(
{
user: userId
},
{
user: userId
},
{
upsert: true,
new: true
},
(err, doc) => callback(err, doc)
);
Since using only findOneAndUpdate would always send queries to the Primary DB, let’s add a buffer with findOne.
From the second time onwards, findOne can always retrieve the document, allowing effective use of Secondary DBs. This also prevents unnecessary findOneAndUpdate queries (that don’t need updates) from being sent to the Primary DB.
// `findOne` is executed in the secondary db at first
// because `findOneAndUpdate` is executed in the primary db.
WishListConfig.findOne({
user: userId
})
.read('secondaryPreferred')
.exec((err, doc) => {
if (err || doc) {
return callback(err, doc);
}
return WishListConfig.findOneAndUpdate(
{
user: userId
},
{
user: userId
},
{
upsert: true,
new: true
},
(err, doc) => callback(err, doc)
);
});
That’s all from the Gemba where I devised ways to reduce the number of queries to the Primary when MongoDB’s Primary DB became heavily loaded.