These days, most cloud servers come with more than one core. But, there is no way to get the benefit of multiple cores with Meteor. Hence, we cannot use the maximum capacity of the server.
Luckily from today onwards, Meteor apps can use multiple cores very easily. This is how.
First add the Cluster package into your app:
meteor add meteorhacks:cluster
Then, expose the following environment variable:
That’s all you have to do. Now your Meteor app will use all the cores available on your server.
If you are using the Meteor Up to deploy your app, update mup and do
You can also specify the number of workers explicitly, like this:
Normally, Cluster needs a MongoDB connection to communicate between servers. But, since these workers were spawned inside a single server, we don’t need a MongoDB connection for multi-core support.
NodeJS supports multiple cores with the cluster module. It works on the TCP layer. But, Meteor needs sticky session support. Because of that, we need to move our multi-core routing logic into the HTTP layer. So, we can’t just use the NodeJS cluster module with Meteor.
Therefore, we had to come up with a different approach to adding multi-core support to Meteor. First, we spawn a set of clones of the running Meteor app (we call them workers). Then, we use a few different ways to distribute the traffic. Here they are:
These will be served directly from the main Meteor app. There is no need to proxy them from workers.
These requests will be proxied to workers we’ve spawned. Sticky session support is enabled when proxying.
For WebSocket requests, we simply send the socket to the worker and then it will directly handle the traffic. In this case, there is no proxying and it’s very efficient. This is similar to how the NodeJS cluster module behaves.
To benchmark the performance, we decided to run a test like this. These tests were done using an Ubuntu server form DigitalOcean that has four cores. We load tested it for a few different cases:
Phusion Passenger is a customized nginx server, which can be used for multi-core support. It supports Meteor apps too.
Here’s how this test app works:
We’ve used three different payloads:
Here is a table of subrates (subscriptions per minute): (These metrics were captured using Kadira)
It seems like in both 20KB and 200 Kb (without caching) tests, Passenger and Cluster performed equally. That’s because a lot CPU time was spent on fetching documents from MongoDB.
But, in the other case, data is cached in the Memory and only a fraction of CPU time was spent on fetching documents. Because of that, the app could handle more requests. This time, Cluster could handle a lot more requests than Passenger. That’s because, Cluster does not proxy requests rather it sends the raw socket to the worker.
So clearly, Cluster uses cores in your server in a more efficient manner compared with Phusion Passenger. That’s a really good thing.
Use cluster with your app and try to utilize all the cores available in your server. You can also use it to scale your Meteor app vertically by adding more cores.
Finally, don’t forget to share your experiences with us.