How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04 (Tutorial)

How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04. Database clustering is a concept that involves multiple servers which are connected to a single primary database. Clustering is a key aspect in production environments to ensure data redundancy, fault tolerance, high availability and load balancing. In this guide, we will demonstrate how to create a MongoDB multi node cluster on Ubuntu 22.04.

Please read on How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04.

What is a MongoDB Multi-Node Cluster?

One of the benefits of MongoDB is that it supports real-time replication of data across multiple servers or nodes. In contrast to a single server MongoDB database, a multi-node cluster comprises a primary server that accepts read and write operations , and two or more secondary servers on which data will be copied or replicated. Replication is made possible across the cluster using a replica set.

A MongoDB replica set is a group of MongoDB instances that maintain consistency of the same data set across a cluster. It enforces replication across  by providing redundancy and high availability in the cluster. Without a replica set in a MongoDB deployment, data would only be saved in the primary node. This would mean that in case of any failure in the primary node, all the data would be lost.

Advantages of implementing a Multi-Node cluster

As previously discussed, a multi node cluster provides the following benefits.

Data Redundancy

In a multi node cluster, all servers are synchronized to store the exact same data. This implies that the primary server has exactly the same data set as the secondary node and this ensures data redundancy which comes in handy in case of a failure on one of the nodes.

Scalability

Scalability is not achieved by default in  a database. It  is only achieved through database clustering where data is  evenly spread out  across multiple servers. A multi-node cluster offers horizontal scaling, which in turn, ensures high availability of data.

High Availability

High availability refers to maintenance of high levels of uptime, often well above the SLAs. This is achieved by eliminating single points of failure, which is made possible through horizontal scaling. High availability ensures that you can access your data at any given time.

Compliance

Implementing a multi-node cluster in a production environment ensures compliance with the relevant laws.

How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04

Lab Setup

For demonstration , we have a  3-node cluster environment as shown . We have a primary node and two secondary nodes.

  1. 173.82.240.178         mongo-master-node
  2. 173.82.240.203         mongo-node-1
  3. 173.82.240.100         mongo-node-2

Without much further ado, let us get started with setting up a MongoDB multi node cluster.

Step 1: Update the hosts file

To  get started, you need to update the hosts file of each node with the IP address and hostname of each node. So, access the file:

				
					$ sudo nano /etc/hosts
				
			

Append the following lines to the file. Be sure to update the IP address and the hostname to correspond with your own setup.

				
					173.82.240.178	mongo-master-node

173.82.240.203  mongo-node-1

173.82.240.100	mongo-node-2
				
			

Save the changes and exit the file.

Step 2: Install MongoDB

The next step is to install MongoDB on all the nodes in your cluster setup. So, log into each node and start by refreshing the local package index.

				
					$ sudo apt update
				
			

Once the system is up to date,  install the following essential packages.

				
					$ sudo apt install software-properties-common gnupg apt-transport-https ca-certificates -y
				
			

Moving on, we will install MongoDB 5.0 which is the latest release at the time of writing this guide. Therefore, begin by adding the  MongoDB GPG key.

				
					$ wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
				
			

Command Output looks like this

				
					OK
				
			

Next, add the MongoDB 5.0 repository to the/etc/apt/sources.list.d directory

				
					$ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
				
			

Then the Command Output should be like this 

				
					deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse
				
			

With the repository in place please update the package lists to notify the system about the newly added repository.

				
					$ sudo apt update
				
			

Then install MongoDB database server.

				
					$ sudo apt install mongodb-org -y
				
			

When the installation is complete, verify that MongoDB server is installed as shown.

				
					$ mongod --version
				
			

You will get this Command Output

				
					db version v5.0.9
Build Info: {
    "version": "5.0.9",
    "gitVersion": "6f7dae919422dcd7f4892c10ff20cdc721ad00e6",
    "openSSLVersion": "OpenSSL 1.1.1f  31 Mar 2020",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2004",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
				
			

Next step is to start and enable MongoDB daemon using the following commands:

				
					$ sudo systemctl start mongod
$ sudo systemctl enable mongod
				
			

Then verify that MongoDB service is running.

				
					$ sudo systemctl status mongod
				
			

Your Command Output

				
					● mongod.service - MongoDB Database Server
     Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-06-17 12:28:15 UTC; 6min ago
       Docs: https://docs.mongodb.org/manual
   Main PID: 14582 (mongod)
     Memory: 63.0M
     CGroup: /system.slice/mongod.service
             └─14582 /usr/bin/mongod --config /etc/mongod.conf

Jul 17 10:20:15 ubuntu systemd[1]: Started MongoDB Database Server.
				
			

Step 3: Create Administrative User on Master Node

Following step is to create an administrative user on the master node. The administrative user will be used to create a  replica set which will be replicated across the two client nodes. 

So, access the MongoDB shell.

				
					$ mongosh
				
			

Switch the database to admin user:

				
					use admin
				
			

Now in here please create an admin user as follows. The ‘passwordPrompt()‘ will prompt you to enter the admin password.

				
					db.createUser(
  {
    user: "admin-user",
    pwd: passwordPrompt(),
    roles: [ { role: "root", db: "admin" }, "readWriteAnyDatabase" ]
 }
)

				
			
create mongodb multi node cluster ubuntu 20.04

Once you have created the  Administrative user, exit the shell.

				
					exit
				
			

Step 4: Configure the Master Node

Moving on, you will be required to generate a key file that will be used to secure authentication across the nodes in the cluster. To generate the key, we will use the openssl command.

So, first, switch to root user.

				
					$ sudo su
				
			

Following step is to generate the key file as follows.

				
					# openssl rand -base64 756 > /mnt/keyfile
				
			

Next assign the necessary file ownership and  permissions.

				
					# chmod 400 /mnt/keyfile
# chown mongodb:mongodb /mnt/keyfile
				
			

Copy the key file to all the nodes in your cluster.

				
					# scp /mnt/keyfile root@173.82.240.203:/mnt/
# scp /mnt/keyfile root@173.82.240.100:/mnt/
				
			

Here please access the default MongoDB configuration file.

				
					# sudo vim /etc/mongod.conf
				
			

Update the configuration file as shown. The Replica Set Name is an arbitrary value and you can give it your preferred name.

				
					
net:
   port: 27017
   bindIp: 127.0.0.1,mongo-master-node

security:
   keyFile: /mnt/keyfile

replication:
   replSetName: "replica01"
				
			

Save the changes and exit the configuration file.

Step 5: Configure the client nodes

In this step  log into each of the client nodes and edit the main configuration file.

				
					$ sudo vim  /etc/mongod.conf
				
			

For Node 1

				
					net:
   port: 27017
   bindIp: 127.0.0.1,mongo-node-1

security:
   keyFile: /mnt/keyfile

replication:
   replSetName: "replica01"

				
			

Save the changes and exit the configuration file.

Next apply the following ownership and permissions to the key file that was copied.

				
					# chmod 400 /mnt/keyfile
# chown mongodb:mongodb /mnt/keyfile
				
			

For the changes to take effect, restart MongoDB service.

				
					$ sudo systemctl restart mongod
				
			

Repeat the same for the remaining client node.

For Node 2

Login and access the main configuration file.

				
					$ sudo vim /etc/mongod.conf
				
			

Make the following changes.

				
					net:
   port: 27017
   bindIp: 127.0.0.1,mongo-node-2

security:
   keyFile: /mnt/keyfile

replication:
   replSetName: "replica01"
				
			

Save the changes and exit.

As before, assign the following ownership and file permissions.

				
					# chmod 400 /mnt/keyfile
# chown mongodb:mongodb /mnt/keyfile
				
			

Be sure to restart MongoDB service to apply the changes made.

				
					$ sudo systemctl restart mongod
				
			

Step 6: Initiate the Replica Set

In this section, we will create a replica set on the master node and later verify replication of the data defined in the replica set.

On the master node, authenticate as the administrative user.

				
					# mongosh -u admin -p --authenticationDatabase admin
				
			

Initialize the replica set as follows.

				
					rs.initiate()

				
			

And your Command Output should be like this 

				
					{
  info2: 'no configuration specified. Using a default configuration for the set',
  me: '173.82.240.178:27017',
  ok: 1
}

				
			

Next step is to add the first node to the cluster.

				
					rs.add("mongo-node-1")
				
			

Similarly, add the second client node.

				
					rs.add("mongo-node-2")
				
			

Command Output

At this point, all the nodes have been added to the cluster.  To check the status of the replica set, run the command:

				
					rs.status()
				
			

Command Output

				
					

replica01 [direct: primary] test > rs.status()
{
  set: 'replica01',
  date: ISODate("2022-07-13T20:22:53.088Z"),
  myState: 1,
  term: Long("1"),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long("2000"),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
    lastCommittedWallTime: ISODate("2022-07-13T20:22:47.186Z"),
    readConcernMajorityOpTime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
    appliedOpTime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
    durableOpTime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
    lastAppliedWallTime: ISODate("2022-07-13T20:22:47.186Z"),
    lastDurableWallTime: ISODate("2022-07-13T20:22:47.186Z")
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1657743717, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate("2022-07-13T20:17:06.963Z"),
    electionTerm: Long("1"),
    lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1657743426, i: 1 }), t: Long("-1") },
    lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1657743426, i: 1 }), t: Long("-1") },
    numVotesNeeded: 1,
    priorityAtElection: 1,
    electionTimeoutMillis: Long("10000"),
    newTermStartDate: ISODate("2022-07-13T20:17:07.061Z"),
    wMajorityWriteAvailabilityDate: ISODate("2022-07-13T20:17:07.152Z")
  },
  members: [
    {
      _id: 0,
      name: '173.82.240.178:27017',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 539,
      optime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2022-07-13T20:22:47.000Z"),
      lastAppliedWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      lastDurableWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1657743426, i: 2 }),
      electionDate: ISODate("2022-07-13T20:17:06.000Z"),
      configVersion: 5,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: 'mongo-node-1:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 222,
      optime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2022-07-13T20:22:47.000Z"),
      optimeDurableDate: ISODate("2022-07-13T20:22:47.000Z"),
      lastAppliedWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      lastDurableWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      lastHeartbeat: ISODate("2022-07-13T20:22:52.451Z"),
      lastHeartbeatRecv: ISODate("2022-07-13T20:22:52.464Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: '173.82.240.178:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 5,
      configTerm: 1
    },
    {
      _id: 2,
      name: 'mongo-node-2:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 174,
      optime: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1657743767, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2022-07-13T20:22:47.000Z"),
      optimeDurableDate: ISODate("2022-07-13T20:22:47.000Z"),
      lastAppliedWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      lastDurableWallTime: ISODate("2022-07-13T20:22:47.186Z"),
      lastHeartbeat: ISODate("2022-07-13T20:22:52.500Z"),
      lastHeartbeatRecv: ISODate("2022-07-13T20:22:51.486Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongo-node-1:27017',
      syncSourceId: 1,
      infoMessage: '',
      configVersion: 5,
      configTerm: 1
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1657743767, i: 1 }),
    signature: {
      hash: Binary(Buffer.from("84b17e5c768b301786b693ea6d4292b200ab01c7", "hex"), 0),
      keyId: Long("7119953804123963394")
    }
  },
  operationTime: Timestamp({ t: 1657743767, i: 1 })
}
				
			

Step 7: Verify replication on client nodes

To simulate simulation of the replica set across the client nodes, we are going to create a database on the master node and add some values to it.

On the master node, authenticate as the Administrative user.

				
					# mongosh -u admin-user -p --authenticationDatabase admin
				
			

Please create a database. In this case, we will create a sample database called testdb.

				
					use testdb
				
			

Here create a collection and add a record. In this example, we are creating a collection called ‘employees‘ that contains employee details.

				
					db.employees.insert({Name: "Andrew", Age: 25, City: "London", Status: "Married"})
				
			

Command Output

To verify the newly created record, run the command:

				
					db.employees.find()

				
			

Command Output

				
					[
  {
    _id: ObjectId("62cf2cbde6e12dec1af9354b"),
    Name: 'Andrew',
    Age: 25,
    City: 'London',
    Status: 'Married'
  }
]
				
			

You can also verify the existence of the database.

				
					show dbs
				
			

Command Output

list-databases-in-mongodb

Now, head over to any of the client nodes and login to MongoDB as the Administrative user.

				
					mongosh -u admin-user -p --authenticationDatabase admin

				
			

Once logged in enable the secondary member read operations on a per-connection basis using the following command

				
					db.getMongo().setReadPref("primaryPreferred")
				
			

Finally, switch to the test database and list the documents in the collection.

				
					use testdb
db.employees.find()
				
			

Command Output

confirm-replication-is-working-on-mongodb-replica-set

This is sure confirmation that the replication is working as expected !

So thank you for reading How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04. It’s time to summarize. 

How to Create MongoDB Cluster Multi-Node on Ubuntu 20.04 Conclusion

This wraps up our guide. In this tutorial, we have demonstrated how to setup and configure a multi-node MongoDB cluster and how to create a replica set and verify replication on secondary nodes. A multi-node cluster environment ensures that copies of your data are available on different servers, and this ensures data redundancy, and high availability. For more information about  MongoDB clusters and replication, check out the Official MongoDB documentation.

Please check our blog content about MongoDB here

Avatar for James Kiarie
James Kiarie

Hello everyone! My name is James, a certified Linux Administrator, and a tech enthusiast with over 5 years of experience in penning down high-quality guides on Linux and Cloud technologies. Outside work hours I enjoy working out, swimming, listening to music, and reading fiction novels.

5 1 vote
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x