Skip to content

Instantly share code, notes, and snippets.

@jspw
Last active June 14, 2023 13:31
Show Gist options
  • Save jspw/9f57f88d8e0f22a453d886c85b5d8472 to your computer and use it in GitHub Desktop.
Save jspw/9f57f88d8e0f22a453d886c85b5d8472 to your computer and use it in GitHub Desktop.
Configure mongodb replica for production

Now, mf you want to connect to the mongodb databse from another machine or like using it in a backend service. What is the connection string ?

Technically mongodb://localhost:2717,localhost:2718,localhost:2719/?replicaSet=myReplicaSet

But as your are trying to connect from another machine, you need the ip address or domain configured for that machine.

  • Connection string : mongodb://146.190.90.245:2717,146.190.90.245:2718,146.190.90.245:2719/?replicaSet=myReplicaSet
  • Use a mongodb client like "MongoDB Compass"
  • Failed or connection timeout!

Can you check which connection port are open for the machine ?

  • nmap 146.190.90.245

      Starting Nmap 7.80 ( https://nmap.org ) at 2023-06-14 12:40 UTC
    Nmap scan report for neogenacademy.com (146.190.90.245)
    Host is up (0.0000060s latency).
    rDNS record for 146.190.90.245: ubuntu-s-4vcpu-8gb-intel-sgp1-01
    Not shown: 995 closed ports
    PORT     STATE    SERVICE
    22/tcp   open     ssh
    80/tcp   open     http
    3000/tcp open     ppp
    5000/tcp open     upnp
    5432/tcp filtered postgresql
    
    Nmap done: 1 IP address (1 host up) scanned in 1.49 seconds
    

- Now access to the mongodb server and check firewall ( you should use firewall)
- `sudo ufw status`

Status: active

To Action From


OpenSSH ALLOW Anywhere
3000/tcp ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
3000/tcp (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)


In mycase, necessary ports (2717, 2718, and 2719) are not open for incoming connections.

- add them :) 

  - `sudo ufw allow 2717`
  - `sudo ufw allow 2718`
  - `sudo ufw allow 2719`

- check : `sudo ufw status` 

Status: active

To Action From


OpenSSH ALLOW Anywhere
3000/tcp ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
2717 ALLOW Anywhere
2718 ALLOW Anywhere
2719 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
3000/tcp (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
2717 (v6) ALLOW Anywhere (v6)
2718 (v6) ALLOW Anywhere (v6)
2719 (v6) ALLOW Anywhere (v6)


  • Install Mongodb in server

  • Create/start multiple mongo servers (my be in different vm or in same server on different port)

    • mongod --port 2717 --dbpath ~/test/mongos/db1 --replSet myReplicaSet
    • mongod --port 2718 --dbpath ~/test/mongos/db2 --replSet myReplicaSet
    • mongod --port 2719 --dbpath ~/test/mongos/db3 --replSet myReplicaSet
  • Open up any mongo server shell (lets say “2717”) which will be your primary mongodb

    • mong --port 2717
  • Check status :

    • rs.status()
      • will find no configuration
  • init

    • rs.initiate()
  • add other servers

    • rs.add(“localhost:2718”)
    • rs.add(“localhost:2719”)
  • check “members” in status again and you will see the primary and secondary servers

    myReplicaSet:PRIMARY> rs.status();
    {
            "set" : "myReplicaSet",
            "date" : ISODate("2023-06-13T13:34:46.479Z"),
            "myState" : 1,
            "term" : NumberLong(1),
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "heartbeatIntervalMillis" : NumberLong(2000),
            "majorityVoteCount" : 2,
            "writeMajorityCount" : 2,
            "votingMembersCount" : 3,
            "writableVotingMembersCount" : 3,
            "optimes" : {
                    "lastCommittedOpTime" : {
                            "ts" : Timestamp(1686663282, 1),
                            "t" : NumberLong(1)
                    },
                    "lastCommittedWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                    "readConcernMajorityOpTime" : {
                            "ts" : Timestamp(1686663282, 1),
                            "t" : NumberLong(1)
                    },
                    "appliedOpTime" : {
                            "ts" : Timestamp(1686663282, 1),
                            "t" : NumberLong(1)
                    },
                    "durableOpTime" : {
                            "ts" : Timestamp(1686663282, 1),
                            "t" : NumberLong(1)
                    },
                    "lastAppliedWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                    "lastDurableWallTime" : ISODate("2023-06-13T13:34:42.447Z")
            },
            "lastStableRecoveryTimestamp" : Timestamp(1686663247, 1),
            "electionCandidateMetrics" : {
                    "lastElectionReason" : "electionTimeout",
                    "lastElectionDate" : ISODate("2023-06-13T13:22:07.203Z"),
                    "electionTerm" : NumberLong(1),
                    "lastCommittedOpTimeAtElection" : {
                            "ts" : Timestamp(1686662527, 1),
                            "t" : NumberLong(-1)
                    },
                    "lastSeenOpTimeAtElection" : {
                            "ts" : Timestamp(1686662527, 1),
                            "t" : NumberLong(-1)
                    },
                    "numVotesNeeded" : 1,
                    "priorityAtElection" : 1,
                    "electionTimeoutMillis" : NumberLong(10000),
                    "newTermStartDate" : ISODate("2023-06-13T13:22:07.232Z"),
                    "wMajorityWriteAvailabilityDate" : ISODate("2023-06-13T13:22:07.252Z")
            },
            "members" : [
                    {
                            "_id" : 0,
                            "name" : "localhost:2717",
                            "health" : 1,
                            "state" : 1,
                            "stateStr" : "PRIMARY",
                            "uptime" : 5197,
                            "optime" : {
                                    "ts" : Timestamp(1686663282, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2023-06-13T13:34:42Z"),
                            "lastAppliedWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "lastDurableWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "syncSourceHost" : "",
                            "syncSourceId" : -1,
                            "infoMessage" : "",
                            "electionTime" : Timestamp(1686662527, 2),
                            "electionDate" : ISODate("2023-06-13T13:22:07Z"),
                            "configVersion" : 7,
                            "configTerm" : 1,
                            "self" : true,
                            "lastHeartbeatMessage" : ""
                    },
                    {
                            "_id" : 1,
                            "name" : "localhost:2718",
                            "health" : 1,
                            "state" : 2,
                            "stateStr" : "SECONDARY",
                            "uptime" : 186,
                            "optime" : {
                                    "ts" : Timestamp(1686663282, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(1686663282, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2023-06-13T13:34:42Z"),
                            "optimeDurableDate" : ISODate("2023-06-13T13:34:42Z"),
                            "lastAppliedWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "lastDurableWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "lastHeartbeat" : ISODate("2023-06-13T13:34:46.450Z"),
                            "lastHeartbeatRecv" : ISODate("2023-06-13T13:34:46.451Z"),
                            "pingMs" : NumberLong(0),
                            "lastHeartbeatMessage" : "",
                            "syncSourceHost" : "localhost:2717",
                            "syncSourceId" : 0,
                            "infoMessage" : "",
                            "configVersion" : 7,
                            "configTerm" : 1
                    },
                    {
                            "_id" : 2,
                            "name" : "localhost:2719",
                            "health" : 1,
                            "state" : 2,
                            "stateStr" : "SECONDARY",
                            "uptime" : 8,
                            "optime" : {
                                    "ts" : Timestamp(1686663282, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(1686663282, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2023-06-13T13:34:42Z"),
                            "optimeDurableDate" : ISODate("2023-06-13T13:34:42Z"),
                            "lastAppliedWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "lastDurableWallTime" : ISODate("2023-06-13T13:34:42.447Z"),
                            "lastHeartbeat" : ISODate("2023-06-13T13:34:46.449Z"),
                            "lastHeartbeatRecv" : ISODate("2023-06-13T13:34:44.951Z"),
                            "pingMs" : NumberLong(0),
                            "lastHeartbeatMessage" : "",
                            "syncSourceHost" : "localhost:2718",
                            "syncSourceId" : 1,
                            "infoMessage" : "",
                            "configVersion" : 7,
                            "configTerm" : 1
                    }
            ],
            "ok" : 1,
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1686663282, 1),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            },
            "operationTime" : Timestamp(1686663282, 1)
    }
    
  • you can remove any server

    • rs.remove("localhost:2718")
  • To check the shits you have done, you can stop one of the server or like primary server then you will find out that one of the secondary server is serving as primary and the one whicbh was primary is now unreachable. Toggle the things as you wish to know more about it.

Now We have configured the MongoDB Replica. Now test them :

Lets create a db in 2017 :

  • show dbs;
  • use test
  • db.user.insert({"name" : "Mehedi hasan Shifat"})
  • db.user.find({})

Will see the resuls. Just to remind you that you have insert data in the primary server.

Now console to another one. A secondary server or replica.

  • mongo --port 2718 Try show dbs
myReplicaSet:SECONDARY> db.user.find({});
Error: error: {
        "topologyVersion" : {
                "processId" : ObjectId("64885caac30fd58ac2e11144"),
                "counter" : NumberLong(8)
        },
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotPrimaryNoSecondaryOk",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1686665147, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1686665147, 1)
}

Error MF! As expected!

Ask chat gpt :3

In a replica set, write operations, including some administrative commands, can only be executed on the primary node. 
By default, secondary nodes do not allow these operations to prevent accidental writes and maintain data consistency.

So, open the shell of secondary server

  • mongo --port 2718
  • approve read : rs.slaveOk()

Wallah!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment