johhny B
johhny B

Reputation: 1452

MongoDB replica set on single machine

I have a single instance (I.e. no virtualisation) of Linux running on a server. I have a single mongod instance that is running. Moving to production I want to implement replica sets. Everything I've read talks about running mongod on multiple machines.

I understand it might not be best practice however is it possible to run replica sets of the same machine. Also, the machine has two hard drives. I want the primary DB to be on the first HD and the replica set on the second hard drive.

Is this setup possible?

Upvotes: 12

Views: 13062

Answers (4)

morteza khadem
morteza khadem

Reputation: 514

I did these actions in mongodb 7 to setup two secondary replica and then setup authorization for them:

  1. copy from main config file:
sudo cp /etc/mongod.conf /etc/mongod_repl1.conf
sudo cp /etc/mongod.conf /etc/mongod_repl2.conf
  1. change replica config files:
nano /etc/mongod_repl1.conf
storage:
  dbPath: /var/lib/mongodb_repl1

systemLog:
  path: /var/log/mongodb/mongod_repl1.log

net:
  port: 27018

replication:
  replSetName: rs0
nano /etc/mongod_repl2.conf
storage:
  dbPath: /var/lib/mongodb_repl2

systemLog:
  path: /var/log/mongodb/mongod_repl2.log

net:
  port: 27019

replication:
  replSetName: rs0
  1. Create directories and set permissions:
sudo mkdir /var/lib/mongodb_repl1
sudo touch /var/log/mongodb/mongod_repl1.log
sudo mkdir /var/lib/mongodb_repl2
sudo touch /var/log/mongodb/mongod_repl2.log
sudo chown mongod:mongod /var/lib/mongodb_repl*
sudo chown mongod:mongod /var/log/mongodb/mongod_repl*.log
  1. copy service file:
sudo cp /lib/systemd/system/mongod.service /etc/systemd/system/mongod_repl1.service
sudo cp /lib/systemd/system/mongod.service /etc/systemd/system/mongod_repl2.service

and then change the config files and update these lines to appropriate configs:

nano /etc/systemd/system/mongod_repl1.service
ExecStart=/usr/bin/mongod --config /etc/mongod_repl1.conf
PIDFile=/var/run/mongodb/mongod_repl1.pid
  1. update systemctl
sudo systemctl daemon-reload
  1. start services:
sudo systemctl start mongod_repl1
sudo systemctl start mongod_repl2

get status:

sudo systemctl status mongod_repl1

if service is running then enable service to auto start when system rebooted:

sudo systemctl enable mongod_repl1
sudo systemctl enable mongod_repl2
  1. update main mongod config file (replication section) nano /etc/mongod.conf
replication:
   replSetName: rs0
  1. restart mongod service
  2. connect to mongod and add replica
# mongosh
rs.initiate()
rs.add({ host: "127.0.0.1:27018" })
rs.add({ host: "127.0.0.1:27019" })

Now try to set user,pass for mongodb

# mongosh

use admin

db.createUser("admin",pwd: passwordPrompt(),{roles:["clusterManager","root","userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]})

then create ssl key for communicate between replica sets

openssl rand -base64 741 > /etc/mongodb.key
chmod 600 /etc/mongodb.key
chown mongod:mongod /etc/mongodb.key

update all mongod config files (3 files) like below lines

nano /etc/mongod.conf
nano /etc/mongod_repl1.conf
nano /etc/mongod_repl2.conf
replication:
  replSetName: rs0

security:
  authorization: enabled
  keyFile: /etc/mongodb.key

restart all services (3 services)

sudo systemctl restart mongod
sudo systemctl restart mongod_repl1
sudo systemctl restart mongod_repl2

if you want to set first mongod as primary everytime, you can set priority for each replica to rs.conf() like this:

{
  _id: 'rs0',
  version: 9,
  term: 28,
  members: [
    {
      _id: 0,
      host: '127.0.0.1:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: Long('0'),
      votes: 1
    },
    {
      _id: 1,
      host: '127.0.0.1:27018',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 0.5,
      tags: {},
      secondaryDelaySecs: Long('0'),
      votes: 1
    },
    {
      _id: 2,
      host: '127.0.0.1:27019',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 0.5,
      tags: {},
      secondaryDelaySecs: Long('0'),
      votes: 1
    }
  ],
  protocolVersion: Long('1'),
  writeConcernMajorityJournalDefault: true,
  settings: {
    chainingAllowed: true,
    heartbeatIntervalMillis: 2000,
    heartbeatTimeoutSecs: 10,
    electionTimeoutMillis: 10000,
    catchUpTimeoutMillis: -1,
    catchUpTakeoverDelayMillis: 30000,
    getLastErrorModes: {},
    getLastErrorDefaults: { w: 1, wtimeout: 0 },
    replicaSetId: ObjectId('65c20af84386cf3ce2be6e86')
  }
}

Upvotes: 2

Jason Norwood-Young
Jason Norwood-Young

Reputation: 493

Here's how I did it on Ubuntu. I wanted to use systemd for the second instance.

Copy our existing MongoDB conf:

sudo cp /etc/mongod.conf /etc/mongod_repl.conf

sudo pico /etc/mongod_repl.conf

Change these lines:

storage:
  dbPath: /var/lib/mongodb_repl

systemLog:
  path: /var/log/mongodb/mongod_repl.log

net:
  port: 27018

replication:
  replSetName: rs0

Create the dirs and files, and assign permissions

sudo mkdir /var/lib/mongodb_repl
sudo chown mongodb:mongodb /var/lib/mongodb_repl
sudo touch /var/log/mongodb/mongod_repl.log
sudo chown mongodb:mongodb /var/log/mongodb/mongod_repl.log

Copy our existing startup file:

sudo cp /lib/systemd/system/mongod.service /etc/systemd/system/mongod_repl.service

If you can't find mongod.service, sudo systemctl status mongod. It looks like:

Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)

sudo pico /etc/systemd/system/mongod_repl.service

Change these lines:

ExecStart=/usr/bin/mongod --config /etc/mongod_repl.conf
PIDFile=/var/run/mongodb/mongod_repl.pid

Let systemctl know we've made some changes: sudo systemctl daemon-reload

Try start it our second server:

sudo systemctl start mongod_repl
sudo systemctl status mongod_repl

If it's not running, have a look at the logs:

sudo tail -n100 /var/log/mongodb/mongod_repl.log
sudo journalctl -n100 -u mongod_repl

(You can add a -f to either of those lines to tail the log)

Log in mongo --port 27018

Great! Now you have a second MongoDB server up and running.

Configure your original server to use the same replication set: sudo pico /etc/mongod.conf

Add this:

replication:
   replSetName: rs0

Restart MongoDB sudo systemctl restart mongod

Now you should be able to go through the process of rs.initiate() on your primary, and then add 127.0.0.1:27018 as your secondary.

Upvotes: 10

Samrun0
Samrun0

Reputation: 96

Yes it is possible to get the replica set up and running on a single machine and this is how I do it for testing:

  1. Install mongodb-org on your machine by following the official instructions and make sure it is starting fine.
  2. Then stop the instance process: sudo systemctl stop mongod
  3. You can now start a new instance with --replSet option by following link. Also, in order to have it running in the background you can use --fork and --logpath to create a child process:
    mongod --fork --port 27017 --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongo_0.log --replSet rs0 --bind_ip localhost,<Your machine's IP address>
    
  4. Then connect to the instance and initiate the replica set in Mongo shell:
    mongo --port 27017
    >rs.initiate()
    
  5. In case you want to stop the process do ps aux | grep mongod and then kill -9 <pid>

Upvotes: 3

Priyank Vaghela
Priyank Vaghela

Reputation: 31

Yes, it is possible.

  1. Create a script: sudo nano mongod.sh
  2. Copy and paste:
sudo mongod --port 27017 --dbpath /var/lib/mongodb --replSet rs0 --bind_ip_all &
sudo mongod --port 27018 --dbpath /var/lib/mongodb2 --replSet rs0 --bind_ip_all &
sudo mongod --port 27019 --dbpath /var/lib/mongodb3 --replSet rs0 --bind_ip_all &
  1. Permit the script to execute: sudo chmod +x mongod.sh

  2. Run the script: ./mongod.sh

  3. Initialize replica set in primary mongo server:

$ mongo
> rs.initiate()

output
{
 "info2" : "no configuration specified. Using a default configuration for the set",
 "me" : "<<YOUR_IP>>:27017",
 "ok" : 1
}
rs0:SECONDARY> rs.add('<<YOUR_IP>>:27018')
{ "ok" : 1 }
rs0:PRIMARY> rs.add('<<YOUR_IP>>:27019')
{ "ok" : 1 }

Now, test with your connection string.

Connection String

mongodb://<YOUR_IP>:27017,<YOUR_IP>:27018,<YOUR_IP>:27019/<DB>?replicaSet=rs0&readPreference=secondary

Note: If you're testing in a local system, then remove --bind_ip_all option for security reasons.

Options

--port: Specify port
--dbpath: Path where the mongod instance stores its data
--replSet: Replica set name
--bind_ip_all: Allow remote connections

Upvotes: 2

Related Questions