Home > MongoDB, NoSQL > MongoDB Learning Notes – Replication Overview and Setup replica set

MongoDB Learning Notes – Replication Overview and Setup replica set

MongoDB provides two flavors of replication: master-slave replication and replica sets. For both, a single primary node receives all writes, and then all secondary nodes read and apply those write to themselves asynchronously. Replica sets additionally ensure automated failover: if the primary goes offline for any reason, then one of the secondary nodes will automatically be promoted to primary, if possible.

The minimum recommended replica sets configuration consists of three nodes. Two of these nodes serve as first-class, persistent mongod instance. Either can act as the replica set primary, and both have a full copy of the data. The third node in the set is an arbiter, which doesn’t replicate data, but merely acts as a kind of neutral observer, when failover is required, the arbiter helps to elect a new primary node.

1. Creating a data directory
I’m using windows and data directory is C:\data

mkdir C:\data\node1
mkdir C:\data\node2
mkdir C:\data\arbiter

2. Start each node as separate mongod (in separate terminal)

cd C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin
C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin>mongod --replSet myapp --dbpath /data/node1 --port 20000
C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin>mongod --replSet myapp --dbpath /data/node2 --port 20001
C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin>mongod --replSet myapp --dbpath /data/arbiter --port 20002

We will get error message:

2015-02-22T11:23:40.449+0700 [rsStart] replSet can’t get local.system.replset config from self or any seed (EMPTYCONFIG)

It’s normal, we need to configure the replica sets.

3. Configure replica sets. Connect to one of the non arbiter mongods.

cd C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin
C:\MongoDB\mongodb-win32-x86_64-2008plus-2.6.6\bin>mongo --host localhost --port 20000

In mongodb console

> rs.initiate()
{
 "info2" : "no configuration explicitly specified -- making one",
 "me" : "bluething-PC:20000",
 "info" : "Config now saved locally. Should come online in about a minute.",
 "ok" : 1
}

But when I add other node I get error message

> rs.add("localhost:20001")
{
 "errmsg" : "exception: can't use localhost in repl set member names except when using it for
 all members",
 "code" : 13393,
 "ok" : 0
}

I must use [1] [2]

rs.add("bluething-PC:20001")
{ "ok" : 1 }
And add arbiter node
rs.add("bluething-PC:20002", {arbiterOnly: true})
{ "ok" : 1 }

To get brief summary of the replica set status use command db.isMaster()

db.isMaster()
{
 "setName" : "myapp",
 "setVersion" : 3,
 "ismaster" : true,
 "secondary" : false,
 "hosts" : [
 "bluething-PC:20000",
 "bluething-PC:20001"
 ],
 "arbiters" : [
 "bluething-PC:20002"
 ],
 "primary" : "bluething-PC:20000",
 "me" : "bluething-PC:20000",
 "maxBsonObjectSize" : 16777216,
 "maxMessageSizeBytes" : 48000000,
 "maxWriteBatchSize" : 1000,
 "localTime" : ISODate("2015-02-22T04:55:30.571Z"),
 "maxWireVersion" : 2,
 "minWireVersion" : 0,
 "ok" : 1
}

A more detailed view of the system is provided by the rs.status() method.

rs.status()
{
 "set" : "myapp",
 "date" : ISODate("2015-02-22T04:57:23Z"),
 "myState" : 1,
 "members" : [
 {
 "_id" : 0,
 "name" : "bluething-PC:20000",
 "health" : 1,
 "state" : 1,
 "stateStr" : "PRIMARY",
 "uptime" : 2152,
 "optime" : Timestamp(1424580874, 1),
 "optimeDate" : ISODate("2015-02-22T04:54:34Z"),
 "electionTime" : Timestamp(1424579472, 1),
 "electionDate" : ISODate("2015-02-22T04:31:12Z"),
 "self" : true
 },
 {
 "_id" : 1,
 "name" : "bluething-PC:20001",
 "health" : 1,
 "state" : 2,
 "stateStr" : "SECONDARY",
 "uptime" : 293,
 "optime" : Timestamp(1424580874, 1),
 "optimeDate" : ISODate("2015-02-22T04:54:34Z"),
 "lastHeartbeat" : ISODate("2015-02-22T04:57:22Z"),
 "lastHeartbeatRecv" : ISODate("2015-02-22T04:57:22Z"),
 "pingMs" : 0,
 "syncingTo" : "bluething-PC:20000"
 },
 {
 "_id" : 2,
 "name" : "bluething-PC:20002",
 "health" : 1,
 "state" : 7,
 "stateStr" : "ARBITER",
 "uptime" : 169,
 "lastHeartbeat" : ISODate("2015-02-22T04:57:21Z"),
 "lastHeartbeatRecv" : ISODate("2015-02-22T04:57:21Z"),
 "pingMs" : 1
 }
 ],
 "ok" : 1
}

During the time replica set comes online, the stateStr field of each node should transition from RECOVERING to PRIMARY, or ARBITER.
To test if the replication set working I insert a document in primary node.

myapp:PRIMARY> use test
switched to db test
myapp:PRIMARY> db.test.insert({text: "test replica"})
WriteResult({ "nInserted" : 1 })
myapp:PRIMARY> show dbs
admin (empty)
local 8.074GB
test 0.078GB

Repication should occur immediately. Conncet to secondary node (in separate terminal) and query for the document just inserted.

myapp:SECONDARY> show dbs
admin (empty)
local 8.074GB
test 0.078GB
myapp:SECONDARY> db.test.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

And I get error. This happen because I connect to secondary and by default we can’t query in secondary. We can use rs.slaveOk() command to allow query in secondary node. [3]

myapp:SECONDARY> rs.slaveOk()
myapp:SECONDARY> db.test.find()
{ "_id" : ObjectId("54e962aedb2387c26957e9b4"), "text" : "test replica" }

 

Categories: MongoDB, NoSQL Tags: , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: