How To Convert Your MongoDB Single Instance Into a Cluster

Is it too much to ask to make my single instance MongoDB into a highly available cluster? Yes, if you trust only on MongoDB’s docs to do that. Save a couple of hours of breaking stuff by following this quick tutorial instead.

Photo by Geran de Klerk on Unsplash — Two is better than one, especially for mongodb instances :)

Let’s start

You have a working, in use with data, standalone mongodb server. Take an image from it and create another server from that image. It’s very useful to do so also to have a backup of course before you start messing with it. Now you have 2 identical standalone mongodb instances.

Now this is the most important point to follow that is not mentioned in the mongodb docs: They assume your new mongo instance is a clean one. A mongodb that was just installed without any auth, users or data. This is not true if you have created the new server from an image of course. So go ahead to that new server and stop the mongod, remove all of its data folder’s files and start mongod back again. Now it is running a clean mongo that is ready to become a secondary.

On both servers edit the mongo config to have a replSetName:

replication:
replSetName: myReplica

On the designated primary (not the one from previous step of course), run:

rs.initiate(
{
_id: "myReplica",
version: 1,
members: [
{ _id: 0, host : "mongo1.mydomain:27017" },
{ _id: 1, host : "mongo2.mydomain:27017" },
]
}
)

This will make the new instance start getting data from the original instance. Now you have a working primary and secondary. It can be verified by running rs.conf()

Wait, you are not done yet

The final super important point to mention that is missed in MongoDB’s docs, is that a primary-secondary cluster is not good enough for mongodb’s high availability- meaning when the primary crash, the secondary won’t be able to “vote itself” to become the new primary. You must have 2 secondaries at least for that to happen, or an arbitrer.

Option 1: Creating another secondary

Just take again another server from the image you have, clean its mongo data files, update replica in mongo config and this time run on the primary rs.add("mongo3.mydomain:27017") to add the new secondary to the cluster. This means of course you need to pay for the same machine size and storage costs. If you don’t need extra survivability or read replica continue to the next option instead.

Option 2: Creating an arbitrer

Just take again another server from the image you have, clean its mongo data files, update replica in mongo config and this time run on the primary:

rs.addArb("mongo-arbitrer1.mydomain:27017")

Summary

Congrats! You have made a standalone into a replicaSet in a few clicks. Of course the best option is to write an automation to create replicaSet clusters from the first place but for a manual one time process for an already in use mongodb I hope this quick tutorial was nicer to follow :)

Yours,

Regev Golan

Software Engineer, Team Lead, DevOps, Infrastructure & Big Data @ HiredScore | Empowering Efficient Growth