Español
Congratulations! Your new NoSQL project is ready for go live. Your single node development environment has been so easy to deploy and work with. But, wait a moment!
Does that environment fit the production requirements? Are you ready for a system failure? How will your system survive a machine crash? Will you support the amount of data required? Are you ready to cope with the concurrent load expected?
So your single node is not enough. You need a proper production environment. You need a cluster.
In this entry, we will compare the effort for deploying a production cluster with two popular NoSQL Document Databases: MongoDB and Couchbase.
For this exercise, we will set up a production ready cluster with the following requirements:
- The data will be distributed evenly in three shards
- The cluster will support the failure of one node without data loosing
- The cluster will support load balancing of the requests
- For setting up the cluster, we will follow the official documentation for both MongoDB and Couchbase.
For those of you that can’t wait, let’s show the results and a short summary. In the next pages will go deep into the details:
|
 |
 |
|
Number of machines required
|
14
|
3
|
|
Load Balancer
|
1
|
Not required
|
|
Number of commands executed
|
128
|
27
|
|
Number of files edited
|
28
|
0
|
This is how the different architectures looks like:
Summary
With this comparison, done following the official documentation from both MongoDB and Couchbase, it is easy to see what the differences between Couchbase and MongoDB are from an operational perspective. It is far easier to create, manage and operate Couchbase all while better utilizing server resources with few servers and better performance.
With Couchbase you also get a better and simpler inter-datacenter replication method to enable Disaster Recovery, High Availability and all at scale.
From development point of view, in MongoDB, you will need to enable sharding at the database level and the collection level. Furthermore, in order to a get an evenly balanced data distribution you will need to choose an appropriate sharding key, which can be tricky and cannot be changed after data insertion [1] [2].
To get an idea of the complexity, take a look at the following statement in the MongoDB documentation [3]:
“IMPORTANT
It takes time and resources to deploy sharding. If your system has already reached or exceeded its capacity, it will be difficult to deploy sharding without impacting your application.
As a result, if you think you will need to partition your database in the future, do not wait until your system is over capacity to enable sharding.”
Architecture details
MongoDB Architecture
We are following this documentation from MongoDB:
According to these recommendations and our initial requirements:
- We will need three Config Servers, each one in its own machine.
- The entry point for the clients are the Router process (mongos). We will use two of them, each one in his own machine.
- We will need a Load Balancer with client affinity. [NOTE: as an alternative to point 2 and 3, we can have one mongos instance on each application server]
- We will use three Shards, with one Replica Set on each one.
- Each Replica Set will contain three mongod instances, each one in its own machine. In total we will use 9 machines for sharding (3 shards x 3 mongod/shard x 1 machine/mongod)
Our MongoDB cluster architecture looks like this:

- Each Replica Set has three processes (mongod) each running on different machines. One of them acts a primary node, taking care of the data writing, and the other two acts as replica nodes, holding a copy of the master data in case of failure of the primary.
- Each shard takes care of a subset of the data. The partitioning is done by choosing a shard key or by a hashing algorithm for each document and that key must be passed in with every call to the database or risk a scattered gather.
- We deploy one replica set on each shard [5].
- Access to the database is done through router nodes (mongos).
- Clients talk to the mongos through a load balancer with client affinity.
With this deployment we need fourteen machines and one load balancer.
Couchbase Architecture
We are following this documentation from Couchbase:
According to these recommendations and our initial requirements:
- In Couchbase, each keyspace is called bucket. Each bucket is divided in a fixed number of partitions (1024), called vBuckets. All the vBuckets are distributed evenly among the nodes in the cluster. In order to divide the data in three shards, we will need 3 nodes, each one running on one machine. In this way, each node will have 1/3 of the data.
- Data is distributed evenly across the Data Service nodes
- Each document in the database is replicated automatically to a different node in the cluster
- Routing is done by directly from your client application code using the Couchbase SDK library. No special routing node or load balancer is needed
In our case, the Couchbase cluster architecture looks like this:

With this deployment we need three machines.
Detailed Installation of environment
For this exercise we will use 14 virtual machines Linux CentOS 7, with 2 Gb RAM each one.
We will name each machine: dbbox1, dbbox2, … dbbox14.
We have used fixed IPs and defined all the hostsnames on /etc/hosts file for all the machines.
MongoDB cluster setup
MongoDB installation
We will install MongoDB on 14 machines . On each machine:
vi /etc/yum.repos.d/mongodb-org-3.0.repo
[EDIT FILE]>>>>
[mongodb-org-3.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.0/x86_64/
gpgcheck=0
enabled=1
<<<<
sudo yum install -y mongodb-org
vi /etc/selinux/config
[EDIT FILE]>>>>
SELINUX=disabled
#SELINUX=enforcing
<<<<<
chkconfig mongod off
systemctl disable firewalld
reboot
(6 commands + 2 file edits) x 14 machines = 84 commands + 28 file edits
Configuration Servers
On 3 machines (dbbox10, dbbox11, dbbox12)
mkdir -p /mongodb/config
export LC_ALL=C
mongod --configsvr --logpath /mongodb/config/log --logappend --dbpath /mongodb/config --fork
3 commands x 3 machines = 9 commands
Routers (mongos)
On two machines (dbbox13, dbbox14)
mkdir /mongodb
mongos --configdb dbbox10:27019,dbbox11:27019,dbbox12:27019 --fork --logappend --logpath /mongodb
2 commands x 2 machines = 4 commands
Shards (mongod)
On nine machines (dbbox1, dbbox2, …, dbbox9)
First we will set up the replica sets
mkdir -p /mongodb/rs1_1
# Note different replica set and port for each process
mongod --shardsvr --replSet rs1 --dbpath /mongodb/rs1_1 --logpath /mongodb/log.rs1 --fork --logappend --smallfiles --oplogSize 50 --port 27001
(on each machine change replicas set names to match the architecture graph)
2 commands x 9 machines = 18 commands
On dbbox1:
mongo --port 27001
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "dbbox1:27001",
"ok" : 1
}
rs1:OTHER> rs.add("dbbox4:27001")
{ "ok" : 1 }
rs1:PRIMARY> rs.add("dbbox7:27001")
{ "ok" : 1 }
3 commands
On dbbox2:
mongo --port 27001
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "dbbox2:27001",
"ok" : 1
}
rs2:OTHER> rs.add("dbbox5:27001")
{ "ok" : 1 }
rs2:PRIMARY> rs.add("dbbox8:27001")
{ "ok" : 1 }
3 commands
On dbbox3:
mongo --port 27001
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "dbbox3:27001",
"ok" : 1
}
rs3:OTHER> rs.add("dbbox6:27001")
{ "ok" : 1 }
rs3:PRIMARY> rs.add("dbbox9:27001")
{ "ok" : 1 }
3 commands
Shards configuration:
On dbbox10:
mongo
mongos> sh.addShard("rs1/dbbox1:27001")
{ "shardAdded" : "rs1", "ok" : 1 }
mongos> sh.addShard("rs2/dbbox2:27001")
{ "shardAdded" : "rs2", "ok" : 1 }
mongos> sh.addShard("rs3/dbbox3:27001")
{ "shardAdded" : "rs3", "ok" : 1 }
4 commands
Check configuration
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5612784c13c13614cd1e823b")
}
shards:
{ "_id" : "rs1", "host" : "rs1/dbbox1:27001,dbbox4:27001,dbbox7:27001" }
{ "_id" : "rs2", "host" : "rs2/dbbox2:27001,dbbox5:27001,dbbox8:27001" }
{ "_id" : "rs3", "host" : "rs3/dbbox3:27001,dbbox6:27001,dbbox9:27001" }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
Total:
128 commands
28 file edits
Couchbase: cluster setup
Couchbase Installation
We will install Couchbase on 3 machines (dbbox1, dbbox2, dbbox3). On each machine:
# Disable swappiness
sudo echo 0 > /proc/sys/vm/swappiness
sudo echo '' >> /etc/sysctl.conf
sudo echo '#Set swappiness to 0 to avoid swapping' >> /etc/sysctl.conf
sudo echo 'vm.swappiness = 0' >> /etc/sysctl.conf
# Disable THP
sudo echo never > /sys/kernel/mm/transparent_hugepage/enabled
sudo echo never > /sys/kernel/mm/transparent_hugepage/defrag
# Download binary
wget http://packages.couchbase.com/releases/4.0.0/couchbase-server-enterprise-4.0.0-centos7.x86_64.rpm
sudo rpm --install couchbase-server-enterprise-4.0.0-centos7.x86_64.rpm
8 commands x 3 machines = 24 commands
Cluster configuration
This can be done from a web browser. In this exercise we will use the CLI interface.
This will be done from one machine (dbbox1).
The first command initializes the cluster. The second command add node 2 to the cluster. The third command add node 3 to the cluster.
/opt/couchbase/bin/couchbase-cli cluster-init -c dbbox1.mysite.com:8091 -u Administrator -p change_it --cluster-username=Administrator --cluster-password=change_it --cluster-ramsize=256 --services=data,index,query
/opt/couchbase/bin/couchbase-cli server-add -c dbbox1.mysite.com:8091 –u Administrator –p change_it --server-add=dbbox2.mysite.com:8091 --services=data,index,query
/opt/couchbase/bin/couchbase-cli server-add -c dbbox1.mysite.com:8091 -u Administrator -p change_it --server-add=dbbox3.mysite.com:8091 --server-add-username=Administrator --server-add-password=change_it --services=data,index,query
3 commands
Total:
27 commands
NOTES
[1] (MongoDB) Shard Keys – http://docs.mongodb.org/manual/core/sharding-shard-key/
[2] (MongoDB) Considerations for Selecting Shard Keys – http://docs.mongodb.org/manual/tutorial/choose-a-shard-key/
[3] (MongoDB) Sharded Cluster Requirements – http://docs.mongodb.org/manual/core/sharded-cluster-requirements/
[4] (MongoDB) Production Cluster Architecture – http://docs.mongodb.org/manual/core/sharded-cluster-architectures-production/
[5] (MongoDB) Deploy a Sharded Cluster – http://docs.mongodb.org/manual/tutorial/deploy-shard-cluster/
[6] (MongoDB) Deploy a Replica Set – http://docs.mongodb.org/manual/tutorial/deploy-replica-set/
[7] (Couchbase) Cluster Setup – http://developer.couchbase.com/documentation/server/4.0/clustersetup/manage-cluster-intro.html
[8] (Couchbase) Command Line Interface reference – http://developer.couchbase.com/documentation/server/4.0/cli/cli-intro.html
[9] (Couchbase) Client Topology Awareness – http://developer.couchbase.com/documentation/server/4.0/concepts/client-topology-awareness.html