Create mongodb replica sets on different machines

Important prerequisites:

  1. Confirm connectivity between machines you want to set as replica set
  2. Confirm the same version of Mongodb is installed on each machine. I tried one with mongo 2.6 and another with mongo 3.0 and totally failed. Then I installed mongo 3.0 on every machine.
  3. Don’t set authentication for all the machines before you manage to set all replica sets. I spent a lot of time boggling by authentication issues.
  4. Suppose we have machine A which has a complete copy of data. All other machines, say B, C, D…. for example, need to sync data from A. Make sure all other machines besides A have a empty mongodb database before starting.

 

Now let’s start using a example where machine A has a complete copy of data and machine B is empty and needs to sync from A.

By default, mongod will read `/etc/mongod.conf` every time it starts. There are two formats of the config file: one is of “setting = value” format (http://docs.mongodb.org/v2.4/reference/configuration-options/) and the other is YAML (http://docs.mongodb.org/manual/reference/configuration-options/). The former format was used before Mongo 2.6 but is compatible for versions afterwards.

I use the same config file (of YAML format) on A and B:

storage:
 dbPath: "/media/mongodb/mongodb"
 directoryPerDB: false
 journal:
 enabled: true
systemLog:
 destination: file
 path: "/var/log/mongodb/mongodb.log"
 logAppend: true
 timeStampFormat: iso8601-utc
replication:
 oplogSizeMB: 10240
 replSetName: "rs0"
net:
 port: <your port>

(The correctness of the format of config file is very important. Sometimes, typos in config file can cause failure of start of a mongodb instance while no exception log can be traced.) 

 

To make the config file taking effect, you need to restart mongodb on both machines:

sudo service mongod restart

 

Now go to A’s mongo shell, initiate its replica state:

rsconfig = {_id:"rs0",members:[{_id:0, host:"machine_B_host:port",priority:1},{_id:1, host:"machine_A_host:port",priority:2}]}
rs.initiate(rsconfig) 

Remember to replace machine A and B’s address:port. If you want A to be PRIMARY as much as possible, set its priority higher than B. After this command, it should return OK now. You can also use `rs.reconfig(rsconfig)` later if you want to modify your configuration.

 

When the first time you start mongod on B, you will find you can’t query anything. For example:

show dbs
2015-07-09T22:52:00.208-0400 E QUERY    Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

That’s fine since B is a secondary server. In order to allow B for querying, you need to use `rs.slaveOk()` on B first.

 

 

Till now, we have set up two machines connecting as a replica set. But they can be easily hacked. For security considerations, we need to use a keyfile as an authentication media on both machines.

 

We first stop mongod instance:

sudo service mongod stop

 

Generate a keyfile following: http://docs.mongodb.org/manual/tutorial/generate-key-file/. Then push this file to both machines. I recommend you to put this file in the data directory, with `mongodb:mongodb` as owner and group,  and 600 permissions. 

 

Now add security specification in ‘/etc/mongod.conf:

storage:
 dbPath: "/media/mongodb/mongodb"
 directoryPerDB: false
 journal:
 enabled: true
systemLog:
 destination: file
 path: "/var/log/mongodb/mongodb.log"
 logAppend: true
 timeStampFormat: iso8601-utc
replication:
 oplogSizeMB: 10240
 replSetName: "rs0"
net:
 port: <your port>
security:
 keyFile: "/media/mongodb/mongodb/mongodb-keyfile"

 

As here suggested, specifying keyFile path automatically enables authentication. So before you start mongod instance with keyFile, you should add user and password to your mongo databases. For example:

use products
db.createUser({
    user: "accountUser",
    pwd: "password",
    roles: [ "readWrite"]
})

 

Now start mongodb again:

sudo service mongod start

 

Reference

http://blog.51yip.com/nosql/1580.html

Leave a comment

Your email address will not be published. Required fields are marked *