Replication In Mongo DB


            Replication is the process of synchronizing data across multiple servers. Replication provides redundancy and increases data availability with multiple copies of data on different database servers. Replication protects a database from the loss of a single server. Replication also allows you to recover from hardware failure and service interruptions. With additional copies of the data, you can dedicate one to disaster recovery, reporting, or backup.



Configure Replication in Ubuntu

Here I am using two server

server1 192.168.0.1  for Primary
server2 192.168.0.2 for Secondary and Arbiter

On server1 : Setup hosts

Add all secondary server in hosts

            sudo gedit /etc/hosts

Add all secondary server Ip

192.168.0.2     server2

On server2 : Setup hosts

Add all secondary server in hosts

            sudo gedit /etc/hosts

Add Primary server Ip

192.168.0.1     server1

On server1 : Setup KeyFile for Replication Auth

1. From the command line, execute the following command. This will generate a long random string  of characters that will be used to increase encryption strength. We pipe the output to a file, which will be used as the Key file.

sudo openssl rand -base64 741 > keyfile  //Create a key file

2. Create the directory where the key will be stored.

sudo mkdir -p /opt/mongodb

3. Copy the file to the new directory.

sudo cp keyfile /opt/mongodb

4. Set the ownership of the keyfile to mongodb.

sudo chown mongodb:mongodb /opt/mongodb/keyfile

5. Set the appropriate file permissions.

sudo chmod 700 /opt/mongodb/keyfile


On server2 : Setup Key File for Replication Auth

Copy and paste key file generated on server1 to server2. Then do same step.

sudo mkdir -p /opt/mongodb
sudo cp keyfile /opt/mongodb
sudo chown mongodb:mongodb /opt/mongodb/keyfile
sudo chmod 700 /opt/mongodb/keyfile

On server1 & server2: Edit mongod.conf

1 .Open the MongoDB configuration file into a text editor using terminal.

            sudo gedit  /etc/mongod.conf

2.  Find the network interfaces section of the configuration file. Set the value of bind Ip to either 0.0.0.0 to allow communication over any network interface or add the IP address of a specific network interface.

            # network interfaces
            net:
              port: 27017
              bindIp: 0.0.0.0        
  
3.  Uncomment security Using the path of the key file created earlier, and set the key File option.

            security:
              keyFile: /opt/mongodb/keyfile

4. Uncomment replication: and set the replSetName option. ReplSetName sets the name of the replication cluster

Replication:
  replSetName: rs0

5. save the config file and run below command to recheck configurations
            sudo service mongod restart
            sudo mongod --config /etc/mongod.conf
  

On server1 : Create user Account


Connect the Mongo console, create user and add permissions.
1.    mongo
2.    use admin
3.    db.createUser( {
    user: "RootAdmin",
    pwd: "admin123",
    roles: [ { role: "root", db: "admin" } ]
  });
4.    db.grantRolesToUser("RootAdmin",["readWriteAnyDatabase"])
5.    db.grantRolesToUser("RootAdmin",["userAdminAnyDatabase"])
Exit from console and add authorization in mongod.config file
sudo gedit  /etc/mongod.conf

Add below key name in security tab
            security:
              keyFile: /opt/mongodb/keyfile
  authorization: enabled

save and  close the config file and restart mongodb

            sudo service mongod restart

check config file data are correct is any tab or space issue following command list errors.

            sudo mongod --config /etc/mongod.conf

 

On server1:Initiate the Replication Set


1. connect server1 in mongo console using authentication
           
            mongo -host server1 --port 27017   -u RootAdmin -p admin123                                                         --authenticationDatabase admin

2. While still in the Mongo console, run the following command.

            rs.initiate()

3. Is it success then  Add the member servers to the cluster. Is any error occur check mongod.log file

            rs0:PRIMARY> rs.add("server2:27017")

4. If the servers were added correctly, you’ll get the following output

        {
            "ok" : 1,
            "operationTime" : Timestamp(1514264584, 1),
            "$clusterTime" : {
                        "clusterTime" : Timestamp(1514264584, 1),
                        "signature" : {
                                    "hash" : BinData(0,"REULf/QTHeVjvxv7vx6i44WQuak="),
                                    "keyId" : NumberLong("6502349030356418561")
                        }
             }
        }

5. Check the status of the replication cluster.

            rs0:PRIMARY> rs.status()

Create Arbiter

You may add an extra mongod instance to a replica set as an arbiter. Arbiters do not maintain a data set. The purpose of an arbiter is to maintain a quorum in a replica set by responding to heartbeat and election requests by other replica set members. Because they do not store a data set, arbiters can be a good way to provide replica set quorum functionality with a cheaper resource cost than a fully functional replica set member with a data set. If your replica set has an even number of members, add an arbiter to obtain a majority of votes in an election for primary. Arbiters do not require dedicated hardware

Here I am configure server2(secondary) as arbiter. so we need to run another instance of mongo db for arbiter

On Server2: Create Second Instance

1. Create copy of mongod.conf file
            sudo cp /etc/mongod.conf /etc/mongod1.conf

2. Create DB path and add permission and ownership

            sudo mkdir /var/lib/mongodb2
            sudo chown mongodb:mongodb /var/lib/mongodb2
            sudo chmod 700 /var/lib/mongodb2

3. Create Log path and add permission and ownership

            sudo mkdir  /var/log/mongodb2/mongod.log
            sudo chown mongodb:mongodb  /var/log/mongodb2/mongod.log
            sudo chmod 700  /var/log/mongodb2/mongod.log

4. Edit newly created  mongod1.conf

            sudo gedit  /etc/mongod1.conf

5. Add in config to run in background

            processManagement:
              fork: true

6. Change port in config

            net:
              port: 27018
              bindIp: 0.0.0.0

7. Change DB path

            storage:
              dbPath: /var/lib/mongodb2
            journal:
              enabled: true

8. Change Log Path

            systemLog:
              destination: file
              logAppend: true
              path: /var/log/mongodb2/mongod.log

9.  Start second instance

             sudo mongod --config /etc/mongod1.conf

10. Connect with primary server

          mongo -host server1 --port 27017   -u RootAdmin -p admin123 
          --authenticationDatabase admin

11. Add arbiter

            rs0:PRIMARY> rs.addArb("server2:27018")

           {
                        "ok" : 1,
                        "operationTime" : Timestamp(1514270776, 1),
                        "$clusterTime" : {
                                    "clusterTime" : Timestamp(1514270776, 1),
                                    "signature" : {
                                               "hash" : BinData(0,"Iv2v17LZeyjVdPBVWwzxEIDFcGg="),
                                               "keyId" : NumberLong("6502349030356418561")
                                    }
                        }
            }
12. Check replication status

            rs0:PRIMARY> rs.status()

13. Check entire replication configuration. You’ll see all three nodes.

            rs0:PRIMARY> rs.config()

    {
            "_id" : "rs0",
            "version" : 3,
            "protocolVersion" : NumberLong(1),
            "members" : [
                        {
                                    "_id" : 0,
                                    "host" : "server1:27017",
                                    "arbiterOnly" : false,
                                    "buildIndexes" : true,
                                    "hidden" : false,
                                    "priority" : 1,
                                    "tags" : {
                                               
                                    },
                                    "slaveDelay" : NumberLong(0),
                                    "votes" : 1
                        },
                        {
                                    "_id" : 1,
                                    "host" : "server2:27017",
                                    "arbiterOnly" : false,
                                    "buildIndexes" : true,
                                    "hidden" : false,
                                    "priority" : 1,
                                    "tags" : {
                                               
                                    },
                                    "slaveDelay" : NumberLong(0),
                                    "votes" : 1
                        },
                        {
                                    "_id" : 2,
                                    "host" : "server2:27018",
                                    "arbiterOnly" : true,
                                    "buildIndexes" : true,
                                    "hidden" : false,
                                    "priority" : 0,
                                    "tags" : {
                                               
                                    },
                                    "slaveDelay" : NumberLong(0),
                                    "votes" : 1
                        }
            ],
            "settings" : {
                        "chainingAllowed" : true,
                        "heartbeatIntervalMillis" : 2000,
                        "heartbeatTimeoutSecs" : 10,
                        "electionTimeoutMillis" : 10000,
                        "catchUpTimeoutMillis" : -1,
                        "catchUpTakeoverDelayMillis" : 30000,
                        "getLastErrorModes" : {
                                   
                        },
                        "getLastErrorDefaults" : {
                                    "w" : 1,
                                    "wtimeout" : 0
                        },
                        "replicaSetId" : ObjectId("5a3cfbfc70a7ca27af575a1c")
            }
    }