Previous : mongoDB replica sets
Replication set creation & configuration
Create a Replication Set
First of create 3 directories for each MongoDB Instance, like so c:\Mongo\DB1, DB2, DB3 etc. Then you would start a Mongo instance using each one of those directories…. (CD to the Mongo directory and type away on your console the following)
@Rem Primary start "a" mongod --dbpath ./db1 --port 30000 --replSet "myDemo" @Rem Secondary start "a" mongod --dbpath ./db2 --port 40000 --replSet "myDemo" @Rem Arbitrator start "a" mongod --dbpath ./db3 --port 50000 --replSet "myDemo"
Notice that each Mongo instance is on a different directory and a different TCP port (because we are setting this up on the same machine and we cant have everyone listening on the standard port of 27017) The “–replset” option will tell mongo the name of the replicaset (myDemo) that all three instances will participate in. Running the above command will start all the 3 instances of the mongo server.
At this point the servers dont know much about each other (i.e. who is the primary, secondary or the arbitrator). All they know is that they belong to the same replica set. We will need to configure the roles of the servers using a configuration script by connecting into one of the servers.
Lets just connect to the primary (even though its really not a primary at this point). so here goes nothing
mongo –port 30000
.This will connect you to the localhost (127.0.0.1) on port 30000. to verify this you could type “db.getmongo()
Next up, we will define and configure the replica set such that it has 3 members. As mentioned earlier the Mongo Shell is a JavaScript interpreter. So we will go ahead and create a JavaScript Object, which will be the configuration or the replica set.
It goes something like this
var configdemo={_id: “myDemo” members: [{ _id: 0; host: ‘localhost:30000’, priority: 10}, { _id: 1; host: ‘localhost:40000’}, { _id: 2; host: ‘localhost:50000’, arbiteronly:true}]};
If you want to see a more verbose and human friendly display of the setting simply type configdemo. IN the configuration above, _id:demo is the name of the replication set and the members are described in an array. This is a very minimalistic and simple setup. for detailed configuration information like geographic redundancy etc see this link.
Notice that the primary has a priority of 10. In a replica set, the higher the priority, the more number of votes ( therefore likely to be promoted to primary) it will get in case of a failure of the primary. Having no priority simply means it will be a secondary. Having an extra attribute of “arbiteronly” tells mongo that the server will not store data and will receive neither read or write request.
To initialize the replication we do
>rs.initiate(configdemo)
{
“info” : “config now saved locally. Should come online in a minute.”
“OK” : 1
}
demo:STARTUP2>
Notice that the prompt changed from “>” to “demo:startup2”. I.E. the replica set name (demo) followed by the status of the current server we are connected to. If you were to hit <enter> again, the prompt changes to
myDemo:PRIMARY>
Since the status has changed from STARTUP to PRIMARY it means that the replication set has started successfully and that we are connected to the “primary”. Since its primary, it can accept new write commands and accept new data. So lets just try that
Verifying that Replication works
myDemo:primary> db.foo.save({_id:1, value: ‘hello there’})
this will enter data into the collection FOO that has an ID of 1 and value of “hello there”.
myDemo:primary> db.foo.find()
{“_id”:1, “value”: ‘hello there’}
AS you can see the record had been saved. Now lets connect to the secondary and see if the data has been replicated. so we connect to the secondary via the command Mongo –port 40000
Mongo –port 40000
MongoDB Shell version: x.x.x
connecting to 127.0.0.1:40000/test
myDemo:secondary>db.foo.find()
error: {“$err” : “not master and slaveok=false”, “code”: 12345}
myDemo:SECONDARY>db.setSlaveOK()
myDemo:secondary>db.foo.find()
{“_id”:1, “value”: ‘hello there’}
The error just simply means that you cant read from a secondary unless you say its OK. So we do just that. SetSlaveOK() is a connection level setting… and presto it magically finds the values saved on the PRIMARY. This shows that the replication was successful.
Replication Fail-over
To demonstrate a replication fail-over simply kill the primary by closing or CTRL-C the primary server console.
doing a
demo:secondary>db.foo.find() yields {“_id”:1, “value”: ‘hello there’}. So it’s still readable.
After a few seconds the secondary gets promoted to primary.
myDemo:Secondary>
myDemo:Primary> db.getMongo()
Connection to 127.0.0.1: 40000
Notice that the primary was previously on port 30000. Now lets resurrect the primary just like we did before
cmd> start "a" mongod --dbpath ./db1 --port 30000 --replSet "myDemo"
We will now connect back into the secondary
cmd>mongo –port 40000
MongoDB Shell version: x.x.x
connecting to 127.0.0.1:40000/test
myDemo:Secondary>
AS you can see its connected back into the secondary (the secondary has been demoted from primary when the Primary came back online)
BTW to get help on the commands available for the repo set (RS) use RS.help().
to get the status of the reposet issue rs.status() and it will give you a very descriptive text with information ranging from the health of the reposet to the roles of each server, their ports , polling intervals etc.
As you can see fail-over is a fairly fast and simple process both in terms of configuration as well as DB performance.
Next up: MongoDB Storage Internals
For all your application development needs, visit www.verbat.com for a fiscally conscious proposal that meets your needs ( So I can keep this blog going as well!!!!)
Alternatively click through the link if you found this article interesting. (This will help the companies Search engine rankings)
Leave a Reply