This page looks best with JavaScript enabled

Mongodb Vol2 Replicasets

 ·  🎃 kr0m

A replica set is a group of Mongo instances that maintain the same dataset or set of data, thus the data will be replicated on different servers achieving high availability of our databases. As for our application, we just need to pass the list of servers to the connection driver we use and it will transparently connect to the correct server.

The topology of a Mongo replica set (RS) defines three figures:

  • Primary: Primary server of the RS, clients connect to it by default to execute queries, both reads and writes.
  • Secondary: Server with data replicated from the Primary server.
  • Arbiter: Server without data, only votes when choosing a new Primary server.

NOTE: Votes to choose a Primary server are cast when there is a change in topology. Mongo does not recommend the use of RS with Arbiters, it is worth setting up an additional node with the replicated dataset.

In this article, uppercase letters will indicate where certain commands should be executed, whether on the Primary, Secondary, or All servers.


ALL

We compile and install MongoDb:

emerge -av dev-db/mongodb

We bind the service to all IPs:

vi /etc/mongodb.conf

bind_ip = 0.0.0.0

PRIMARY

We access the MongoDb CLI:

mongo

We create the admin user:

use admin
db.createUser(
  {
    user: "admin",
    pwd: "PASSWORD",
    roles: [ "root" ]
  }
)

We create the RS admin user:

db.createUser(
  {
    user: "clusterAdmin",
    pwd: "PASSWORDRS",
    roles: [ "root" ]
  }
)

TODOS

We enable authentication:

vi /etc/mongodb.conf

security:
    authorization: enabled

We restart the service:

/etc/init.d/mongodb restart


PRIMARY

Mongo RS nodes communicate securely with each other either through SSL certificates that must be renewed every X time or through key files.

We generate the key files:

openssl rand -base64 756 > /etc/mongodb.key
chmod 400 /etc/mongodb.key
chown mongodb:mongodb /etc/mongodb.key

We copy the key to all RS servers and assign them the same permissions as before.


TODOS

vi /etc/mongodb.conf
security:
    keyFile: /etc/mongodb.key
replication:
    replSetName: rs0

We restart the service:

/etc/init.d/mongodb restart


PRIMARY

mongo -u “clusterAdmin” -p “PASSWORDRS” --authenticationDatabase “admin”
rs.initiate(
  {
    _id : 'rs0',
    members: [
      { _id : 0, host : "kr0mtest:27017" },
      { _id : 1, host : "kr0mtest2:27017" },
      { _id : 2, host : "kr0mtest3:27017" }
    ]
  }
)
rs0:SECONDARY>

After a while, a PRIMARY will be elected:

rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2020-04-17T10:38:46.841Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1587119923, 1),
            "t" : NumberLong(1)
        },
        "readConcernMajorityOpTime" : {
            "ts" : Timestamp(1587119923, 1),
            "t" : NumberLong(1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1587119923, 1),
            "t" : NumberLong(1)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1587119923, 1),
            "t" : NumberLong(1)
        }
    },
    "lastStableCheckpointTimestamp" : Timestamp(1587119903, 1),
    "members" : [
        {
            "_id" : 0,
            "name" : "kr0mtest:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 265286,
            "optime" : {
                "ts" : Timestamp(1587119923, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-04-17T10:38:43Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "electionTime" : Timestamp(1586854672, 1),
            "electionDate" : ISODate("2020-04-14T08:57:52Z"),
            "configVersion" : 1,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 1,
            "name" : "kr0mtest2:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 84614,
            "optime" : {
                "ts" : Timestamp(1587119923, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1587119923, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-04-17T10:38:43Z"),
            "optimeDurableDate" : ISODate("2020-04-17T10:38:43Z"),
            "lastHeartbeat" : ISODate("2020-04-17T10:38:44.999Z"),
            "lastHeartbeatRecv" : ISODate("2020-04-17T10:38:44.998Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "kr0mtest3:27017",
            "syncSourceHost" : "kr0mtest3:27017",
            "syncSourceId" : 2,
            "infoMessage" : "",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "kr0mtest3:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 265265,
            "optime" : {
                "ts" : Timestamp(1587119923, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1587119923, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-04-17T10:38:43Z"),
            "optimeDurableDate" : ISODate("2020-04-17T10:38:43Z"),
            "lastHeartbeat" : ISODate("2020-04-17T10:38:45.870Z"),
            "lastHeartbeatRecv" : ISODate("2020-04-17T10:38:45.888Z"),
            "pingMs" : NumberLong(1),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "kr0mtest:27017",
            "syncSourceHost" : "kr0mtest:27017",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1,
    "operationTime" : Timestamp(1587119923, 1),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1587119923, 1),
        "signature" : {
            "hash" : BinData(0,"xSsKDy+0YUJcBM4vpFN0VaJa+rg="),
            "keyId" : NumberLong("6815488928334741505")
        }
    }
}
If you liked the article, you can treat me to a RedBull here