Background: I'm trying to optimize the speed of my Node.js API, built with Express and Mongoose on the Amazon Cloud. I have one API call that takes a good amount of time to run (my /stats API call compiles data from lots of sources, and thus makes hundreds of mongo queries and thus takes about 20 seconds to run). I have noticed that, while this API call is running, other API calls that also hit the Mongo replica set are slow to return. My first thought was that the stats queries were slow, thus blocking, but according to my stat panel I don't have any queries taking > 100ms to run, and also my Mongo DB stats are all in pretty healthy ranges (20+ queries per second, <1% btree miss, <5% lock).
Question: Right now, my Node.js app establishes a single connection to the Mongo set on startup, and all queries use that connection. Would it be better to establish multiple connections? Eg, should I establish a new Mongo connection for each inbound API request, instead? Or, maybe I should have a static number of connections to the replica set, and load-balance between those connections when executing queries?
Or maybe I'm completely off-base?
MongoDB allows multiple clients to read and write the same data. To ensure consistency, MongoDB uses locking and concurrency control to prevent clients from modifying the same data simultaneously.
Your M2 cluster has three nodes with a 500 connection limit per node. Atlas reserves 10 connections per node. If you set your read preference to secondary, Atlas can read from the two secondary nodes for a combined 980 connection limit.
MongoDB represents the data as a collection of documents rather than tables related by foreign keys. This makes it possible for the varied types of data dealt over the internet to be stored decently and accessed in the web applications using Node. js.
You absolutely should be using more than a single connection as otherwise only one query can be executing at a time. The cleanest way to do this is to simply enable connection pooling on your mongodb.Server
object when creating your Db
object. For example:
var serverOptions = {
'auto_reconnect': true,
'poolSize': 5
};
var mdb = new mongodb.Db('test', new mongodb.Server('127.0.0.1', 27017, serverOptions));
mdb.open(function (err, mdb) { ... }
The reason you're not seeing slow query times in the stats is that your concurrent queries are simply queuing up on the client side waiting for the connection to become available. That waiting time won't show up in the server-side query times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With