======Overview====== So far we configured and spoke about two possible configurations with Mongo: * Replication * Sharding Let's discuss overview of each at a time: ====Replication==== This configuration is known also as Active / Passive {{:mongorep.jpg?400|}} Pros: * Provides redundancy in case you loose your site * Can be used as backup site and thus not loading the primary * Can be used for select only queries Cons: * Requires additional Server on other location * Requires further configuration in case of a failover * Secondary servers cannot be used for read/write operations ====Sharding==== This configuration is known as Active / Active {{:mongoshard.jpg?400|}} Pros: * Provides load balanced configuration * Increases the performance * Can be used to store regional data, thus each region accesses it's data way faster Cons: * Requires additional server on the same location * In case of even one server shuts down, its collections aren't available. * Backups should be taken separately for each shard server. ======Replicated Shards====== So, what if we can combine both architectures, as so: {{:mongorepshrd.jpg?300|}} As so, we can combine the PROs of both configuration and eliminates almost all CONs. =====Configuration===== Configuration isn't done so differently than the previous implementations, we have to just combine both ways as follows: ====Configuration Database==== The setup for the configuration database is like any other Mongo database and it is started as follows: [root@lparamongo mongo]# mongod -f /etc/mongod.conf -fork --configsvr about to fork child process, waiting until server is ready for connections. forked process: 1336 child process started successfully, parent exiting [root@lparamongo mongo]# With this, we started a mongo database on port 9005 with db path /app/mongo and as a CONFIGSVR! You can also replicate that database for more redundancy if you wish. ====Shard Controller==== Shard controller is used for the Shard server re-configuration (Addition or Removal of a node for example) or as a proxy (front point) for the clients to connect and be load-balanced among the shards. [root@lparbmongo ~]# mongos --configdb lparamongo:9005 --port 9005 --chunkSize 1 2018-06-07T15:02:37.778+0200 warning: running with 1 config server should be done only for testing purposes and is not recommended for production 2018-06-07T15:02:37.781+0200 [mongosMain] MongoS version 2.6.12 starting: pid=1283 port=9005 64-bit host=lparbmongo (--help for usage) 2018-06-07T15:02:37.781+0200 [mongosMain] db version v2.6.12 2018-06-07T15:02:37.781+0200 [mongosMain] git version: d73c92b1c85703828b55c2916a5dd4ad46535f6a 2018-06-07T15:02:37.781+0200 [mongosMain] build info: Linux build5.ny.cbi.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49 2018-06-07T15:02:37.781+0200 [mongosMain] allocator: tcmalloc 2018-06-07T15:02:37.781+0200 [mongosMain] options: { net: { port: 9005 }, sharding: { chunkSize: 1, configDB: "lparamongo:9005" } } 2018-06-07T15:02:37.829+0200 [mongosMain] creating WriteBackListener for: lparamongo:9005 serverID: 000000000000000000000000 018-04-06T20:11:11.070+0200 [Balancer] warning: could not initialize balancer, please check that all shards and config servers are up: socket exception [CONNECT_ERROR] for lparcmongo:9005 2018-04-06T20:11:11.070+0200 [Balancer] will retry to initialize balancer in one minute ^C2018-04-06T20:11:23.910+0200 [signalProcessingThread] got signal 2 (Interrupt), will terminate after current cmd ends 2018-04-06T20:11:58.751+0200 [mongosMain] writing initial config version at v5 2018-04-06T20:11:58.760+0200 [mongosMain] about to log new metadata event: { _id: "lparbmongo-2018-04-06T18:11:58-5ac7b86e1bf26be6f336303e", server: "lparbmongo", clientAddr: "N/A", time: new Date(1523038318760), what: "finished upgrade of config database", ns: "config.version", details: { from: 0, to: 5 } } 2018-04-06T20:11:58.790+0200 [mongosMain] upgrade of config server to v5 successful 2018-04-06T20:11:58.790+0200 [mongosMain] distributed lock 'configUpgrade/lparbmongo:9005:1523038318:1804289383' unlocked. 2018-04-06T20:11:59.023+0200 [mongosMain] scoped connection to lparamongo:9005 not being returned to the pool 2018-04-06T20:11:59.023+0200 [Balancer] about to contact config servers and shards 2018-04-06T20:11:59.024+0200 [mongosMain] waiting for connections on port 9005 2018-04-06T20:11:59.024+0200 [Balancer] config servers and shards contacted successfully 2018-04-06T20:11:59.024+0200 [Balancer] balancer id: lparbmongo:9005 started at Apr 6 20:11:59 2018-04-06T20:11:59.053+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1523038318:1804289383' acquired, ====Replica Set A==== Each Replica Set should be started, initialized and configured as follows: ===Starting Node 1=== [root@lparcmongo app]# mongod --dbpath /app/mongo2 --logpath /app/mongo2/logmong.log --port 9006 --fork --replSet repSetA about to fork child process, waiting until server is ready for connections. forked process: 1553 child process started successfully, parent exiting ===Starting Node 2=== [root@lparcmongo mongo]# mongod --dbpath /app/mongo --logpath /app/mongo/logmong.log --port 9005 --fork --replSet repSetA about to fork child process, waiting until server is ready for connections. forked process: 1899 child process started successfully, parent exiting Once both Nodes has been started, we can initiate the replica set configuration: [root@lparcmongo mongo]# mongo --port 9005 MongoDB shell version: 2.6.12 connecting to: 127.0.0.1:9005/test > use admin switched to db admin > rs.initiate() { "info2" : "no configuration explicitly specified -- making one", "me" : "lparcmongo:9005", "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } > rs.status() { "set" : "repSetA", "date" : ISODate("2018-04-06T18:07:13Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lparcmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 42, "optime" : Timestamp(1523038024, 1), "optimeDate" : ISODate("2018-04-06T18:07:04Z"), "electionTime" : Timestamp(1523038024, 2), "electionDate" : ISODate("2018-04-06T18:07:04Z"), "self" : true } ], "ok" : 1 } Once we are done we can add the 2nd node to the First Replica set: repSetA:PRIMARY> rs.add("lparcmongo:9006") { "ok" : 1 } repSetA:PRIMARY> rs.status() { "set" : "repSetA", "date" : ISODate("2018-04-06T18:07:45Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lparcmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 74, "optime" : Timestamp(1523038061, 1), "optimeDate" : ISODate("2018-04-06T18:07:41Z"), "electionTime" : Timestamp(1523038024, 2), "electionDate" : ISODate("2018-04-06T18:07:04Z"), "self" : true }, { "_id" : 1, "name" : "lparcmongo:9006", "health" : 1, "state" : 5, "stateStr" : "STARTUP2", "uptime" : 4, "optime" : Timestamp(0, 0), "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-04-06T18:07:43Z"), "lastHeartbeatRecv" : ISODate("2018-04-06T18:07:44Z"), "pingMs" : 0, "lastHeartbeatMessage" : "initial sync need a member to be primary or secondary to do our initial sync" } ], "ok" : 1 Once the 2nd Server has been added we should see the following output from the rs.status() command: repSetA:PRIMARY> rs.status() { "set" : "repSetA", "date" : ISODate("2018-04-06T18:08:00Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lparcmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", <- Primary / Active "uptime" : 89, "optime" : Timestamp(1523038061, 1), "optimeDate" : ISODate("2018-04-06T18:07:41Z"), "electionTime" : Timestamp(1523038024, 2), "electionDate" : ISODate("2018-04-06T18:07:04Z"), "self" : true }, { "_id" : 1, "name" : "lparcmongo:9006", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", <- Secondary / Passive "uptime" : 19, "optime" : Timestamp(1523038061, 1), "optimeDate" : ISODate("2018-04-06T18:07:41Z"), "lastHeartbeat" : ISODate("2018-04-06T18:07:59Z"), "lastHeartbeatRecv" : ISODate("2018-04-06T18:08:00Z"), "pingMs" : 0, "syncingTo" : "lparcmongo:9005" } ], "ok" : 1 } ====Replica Set B==== The replica B is configured the same way as replica A: [root@lpardmongo mongo]# mongod --dbpath /app/mongo --logpath /app/mongo/logmong.log --port 9005 --fork --replSet repSetB about to fork child process, waiting until server is ready for connections. forked process: 1290 child process started successfully, parent exiting [root@lpardmongo mongo2]# mongod --dbpath /app/mongo2 --logpath /app/mongo2/logmong.log --port 9006 --fork --replSet repSetB about to fork child process, waiting until server is ready for connections. forked process: 1341 child process started successfully, parent exiting [root@lpardmongo mongo2]# mongo --port 9005 MongoDB shell version: 2.6.12 connecting to: 127.0.0.1:9005/test > use admin switched to db admin > rs.initiate() { "info2" : "no configuration explicitly specified -- making one", "me" : "lpardmongo:9005", "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } > rs.status() { "set" : "repSetB", "date" : ISODate("2018-04-06T18:10:37Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lpardmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 117, "optime" : Timestamp(1523038227, 1), "optimeDate" : ISODate("2018-04-06T18:10:27Z"), "electionTime" : Timestamp(1523038227, 2), "electionDate" : ISODate("2018-04-06T18:10:27Z"), "self" : true } ], "ok" : 1 } repSetB:PRIMARY> rs.add("lpardmongo:9006 2018-04-06T20:10:47.691+0200 SyntaxError: Unexpected token ILLEGAL repSetB:PRIMARY> rs.add("lpardmongo:9006") { "ok" : 1 } repSetB:PRIMARY> rs.status() { "set" : "repSetB", "date" : ISODate("2018-04-06T18:10:55Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lpardmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 135, "optime" : Timestamp(1523038253, 1), "optimeDate" : ISODate("2018-04-06T18:10:53Z"), "electionTime" : Timestamp(1523038227, 2), "electionDate" : ISODate("2018-04-06T18:10:27Z"), "self" : true }, { "_id" : 1, "name" : "lpardmongo:9006", "health" : 1, "state" : 5, "stateStr" : "STARTUP2", "uptime" : 2, "optime" : Timestamp(0, 0), "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-04-06T18:10:55Z"), "lastHeartbeatRecv" : ISODate("2018-04-06T18:10:55Z"), "pingMs" : 0, "lastHeartbeatMessage" : "initial sync need a member to be primary or secondary to do our initial sync" } ], "ok" : 1 } repSetB:PRIMARY> rs.status() { "set" : "repSetB", "date" : ISODate("2018-04-06T18:10:57Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "lpardmongo:9005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 137, "optime" : Timestamp(1523038253, 1), "optimeDate" : ISODate("2018-04-06T18:10:53Z"), "electionTime" : Timestamp(1523038227, 2), "electionDate" : ISODate("2018-04-06T18:10:27Z"), "self" : true }, { "_id" : 1, "name" : "lpardmongo:9006", "health" : 1, "state" : 5, "stateStr" : "STARTUP2", "uptime" : 4, "optime" : Timestamp(0, 0), "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-04-06T18:10:57Z"), "lastHeartbeatRecv" : ISODate("2018-04-06T18:10:57Z"), "pingMs" : 0, "lastHeartbeatMessage" : "initial sync need a member to be primary or secondary to do our initial sync" } ], "ok" : 1 } repSetB:PRIMARY> =====Configure the Replicated Shards===== So in order to add the replicaSets instead of the servers themselves, we have to add them in a special way: [root@lparbmongo ~]# mongo --port 9005 MongoDB shell version: 2.6.12 connecting to: 127.0.0.1:9005/test mongos> sh.addShard("repSetA/lparcmongo:9005") <- Replica Set Name / one of the members : Port number { "shardAdded" : "repSetA", "ok" : 1 } mongos> sh.addShard("repSetB/lpardmongo:9005") <- Replica Set Name / one of the members : Port number { "shardAdded" : "repSetB", "ok" : 1 } mongos> sh.enableSharding("ShardDB") <- Create Sharded DB { "ok" : 1 } mongos> sh.shardCollection("ShardDB.shardCollection",{shardKey:1}) <- Create a sharded Collection using Sharded Key. { "collectionsharded" : "ShardDB.shardCollection", "ok" : 1 } mongos> show dbs ShardDB 0.078GB admin (empty) config 0.016GB mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 4, "minCompatibleVersion" : 4, "currentVersion" : 5, "clusterId" : ObjectId("5ac7b86e1bf26be6f336303d") } shards: { "_id" : "repSetA", "host" : "repSetA/lparcmongo:9005,lparcmongo:9006" } { "_id" : "repSetB", "host" : "repSetB/lpardmongo:9005,lpardmongo:9006" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : false, "primary" : "repSetA" } { "_id" : "ShardDB", "partitioned" : true, "primary" : "repSetA" } ShardDB.shardCollection shard key: { "shardKey" : 1 } chunks: repSetA 1 { "shardKey" : { "$minKey" : 1 } } -->> { "shardKey" : { "$maxKey" : 1 } } on : repSetA Timestamp(1, 0) mongos> =====Outcome===== In the end, the shard controller will display something similar: 2018-06-07T15:14:13.627+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fa5c55b88e9e647af06 2018-06-07T15:14:13.874+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:19.877+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fabc55b88e9e647af07 2018-06-07T15:14:19.887+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:25.890+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fb1c55b88e9e647af08 2018-06-07T15:14:25.899+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:31.903+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fb7c55b88e9e647af09 2018-06-07T15:14:31.935+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:37.942+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fbdc55b88e9e647af0a 2018-06-07T15:14:37.980+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:43.284+0200 [LockPinger] cluster lparamongo:9005 pinged successfully at Thu Jun 7 15:14:43 2018 by distributed lock pinger 'lparamongo:9005/lparbmongo:9005:1528377223:1804289383', sleeping for 30000ms 2018-06-07T15:14:43.983+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fc3c55b88e9e647af0b 2018-06-07T15:14:43.991+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:49.994+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fc9c55b88e9e647af0c 2018-06-07T15:14:50.269+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:14:56.271+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fd0c55b88e9e647af0d 2018-06-07T15:14:56.279+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:15:02.282+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fd6c55b88e9e647af0e 2018-06-07T15:15:02.290+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' unlocked. 2018-06-07T15:15:08.293+0200 [Balancer] distributed lock 'balancer/lparbmongo:9005:1528377223:1804289383' acquired, ts : 5b192fdcc55b88e9e647af0f