** Diagrams updated on May 22nd. Thanks to Leif Walsh from Tokutek for his feedback.
Replica Sets are a great way to replicate MongoDB data across multiple servers and have the database automatically failover in case of server failure. Read workloads can be scaled by having clients directly connect to secondary instances. Note that master/slave MongoDB replication is not the same thing as a Replica Set, and does not have automatic failover.
Since replication is asynchronous, the data on secondary instances might not be the latest.
Sharding is a way to split data across multiple servers. In a MongoDB Sharded Cluster, the database will handle distribution of the data and dynamically load-balance queries. So, if you have a high write workload, then sharding is the way to go. MongoDB uses a shard key to split collections and migrate the ‘chunks’ to the correct shard.
It is important to pick a good shard key and avoid “hot spots”, so that data is evenly spread between shards and writes are also evenly distributed. In the picture below you see an example with two shards, each shard consists of a replica set.
Migration from a Replica Set to a Sharded setup is pretty easy, but should not be done when the system is busy. The splitting/migration of chunks creates extra load, and can bring a busy system to a standstill.
Additional configuration and routing processes are added to manage the data and query distribution. Config servers store the meta data for the sharded cluster, and are kept consistent by using a two phase commit. Routers are the processes that clients connect to, and queries are then routed to the appropriate shard.
Sharding does add some more complexity, since there are more processes to manage. However, if your performance is degrading and tuning of your application or your existing instances are not helping, then you probably need to look into sharding.
We will deploy a replica set called rs0. This replica set will have as primary node mongo1replicating to two secondary instances mongo2 and mongo3. Install MongoDB on all three servers. On each of MongoDB server, create a configuration file as below:
And add the following lines:
Create the Mongodb data directory:
Start the mongod process on every server:
Connect to mongo shell and initiate replication on mongo1:
Add all replication members to the replica set:
New replica sets elect a primary within a few seconds. Check the replication status:
Check the status until you see the syncingTo value:
Import a test database from http://media.mongodb.org/zips.json into the replica set:
At the moment, we have a replica set (rs0) with a database (mydb) and a collection (zip) on 3 servers (mongo1, mongo2,mongo3).
In a Sharded Cluster, another 2 new roles will be added: mongos and mongod config. mongosis a routing service for MongoDB Sharded Clusters, it determines the location of the data in the cluster, and forwards operations to the right shard. mongos requires mongod config, which stores the metadata of the cluster. All mongos instances must specify the mongod config hosts to the --configdb setting in the same order, and the mongos will read from the first config server (if it cannot connect to the config server, it will move on to the next on the list).
Previously, our mongod replication instance listened on TCP port 27017. We are going to change this to listen to another port (27018) since mongos will take over port 27017 to serve queries from clients. mongod config will use port 27019 to serve the cluster metadata.
We will now stop our mongod instances, change ports and activate sharding:
To make configuration more simple, we will rename our configuration file from/etc/mongodb.conf to /etc/mongodb_shard.conf and add the following line:
Next, create a configuration file for mongod config, /etc/mongodb_config.conf and add the following lines:
Make sure the mongod config data directory exists:
Start the mongod config instance:
Create another configuration file for mongos, /etc/mongos.conf and add the following lines:
Start the mongos and mongod shard instances:
Our Replica Set is listening on port 27018. We need to change the replication setting on the primary mongod instance to this new port. Connect through mongo shell:
And execute following command:
Verify the replication status:
Add rs0 to our Shard Cluster by first connecting to mongos:
Then execute the following command:
Enable sharding on the database mydb that we imported earlier:
Verify the shard status:
Now, our replica set (rs0) is running as a shard in our Sharded Cluster.
Connect through any of the mongos, lets say mongo2:
And try to query some data on database mydb and collection zip:
Congratulations, you have now converted your MongoDB replica set into replicated Sharded Cluster! To add monitoring and cluster management to your Sharded Cluster, you can follow this post to install ClusterControl for MongoDB.