MongoDB setup on your local dev environment is rather easy task. Basically you download MongoDB, install it and configure mongod (database process) to run as a Windows Service. All connection strings are already by default in your Sitecore ConnectionStrings.config file. That’s easy. But how to deal with it on production environment, when things are more complicated, cause you have to ensure required level of availability. In other words you need to be sure that your Sitecore solution will still work, even if some of its component, hosting MongoDB fails.
The easiest way to provide such setup is using MongoDB replication. How does it work?
You start with MongoDB installation on more machines: at least on two (or rather three, if you use arbiter) and configure replica set. In this set you have separate mongod process running on each machine, connected with each other. Every node in the set has its own role:
- Primary – this is the primary data storage used for read & write. If data in your MongoDB is modified it’s replicated from this node to Secondary node(s).
- Secondary – this is the secondary data storage used for read. There could be more than one Secondary node in the set. If Primary fails one of the Secondary nodes may become the new Primary.
- Arbiter – the only role of this node is to promote one of the Secondary node to become the new Primary, in case Primary instance failed. Arbiter doesn’t store the data.
Sitecore communicate with Primary and Secondary nodes, each instance in the replica set should also be able to communicate with the others.
Replica set configuration
Prerequisites
We need to install & run MongoDB on all machines and check if all nodes are able to talk with each other. We can use telnet or try to connect to MongoDB instance using mongo shell command from your MongoDB installation folder:
1 |
mongo --host mongo2.smartsitecore.com --port 27017 |
Repeat this step on all machines and try to connect to all instances.
Output should be “connecting to: mongo2.smartsitecore.com:27017/test”
Primary node configuration
First we need to change mongod configuration file on Primary by adding following lines (if you don’t use YAML syntax, just add replSet=rs0). rs0 will be the name of our set:
1 2 |
replication: replSetName: rs0 |
After changing configuration it’s necessary to restart mongod process. Now we are ready to call mongo shell again on Primary node:
1 |
rs.initiate( { _id : "rs0", members: [ { _id : 0, host : "mongo1.smartsitecore.com:27017" } ]}) |
result should be { “ok” : 1}
Secondary node configuration
We need to change mongod configuration file on Secondary by adding same lines as on Primary:
1 2 |
replication: replSetName: rs0 |
Restart mongod on Secondary node. Then on the Primary node run rs.add() command from mongo shell
1 |
rs.add("mongo2.smartsitecore.com") |
Again result should be { “ok” : 1}
Arbiter node configuration
Change mongod configuration file on Arbiter, by adding the same replication set name and disable journal for storage (for non YAML syntax use journal.enabled=false). You can safely disable journal, cause Arbiter will not store any data, besides the configuration.
1 2 3 4 5 |
replication: replSetName: rs0 storage: journal: enabled: false |
Restart mongod on Arbiter node. Then on the Primary node run rs.addArb() command from mongo shell
1 |
rs.addArb("mongo3.smartsitecore.com") |
Result should be again { “ok” : 1}
Checking Replica set status
We need again run mongo shell command on one of the instances and call replication status command:
1 |
rs.status() |
the output should look like below. We have three nodes in the set and all are operating:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
MongoDB shell version: 3.2.8 connecting to: test Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user rs0 :PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-02-17T07:23:45.147Z"), "myState" : 7, "term" : NumberLong(31), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "mongo1.smartsitecore.com:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 6902238, "optime" : { "ts" : Timestamp(1487316177, 1), "t" : NumberLong(31) }, "optimeDate" : ISODate("2017-02-17T07:22:57Z"), "lastHeartbeat" : ISODate("2017-02-17T07:23:40.893Z"), "lastHeartbeatRecv" : ISODate("2017-02-17T07:23:43.567Z" ), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1480413608, 1), "electionDate" : ISODate("2016-11-29T10:00:08Z"), "configVersion" : 3 }, { "_id" : 1, "name" : "mongo2.smartsitecore.com:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 6902238, "optime" : { "ts" : Timestamp(1487316177, 1), "t" : NumberLong(31) }, "optimeDate" : ISODate("2017-02-17T07:22:57Z"), "lastHeartbeat" : ISODate("2017-02-17T07:23:41.162Z"), "lastHeartbeatRecv" : ISODate("2017-02-17T07:23:44.450Z" ), "pingMs" : NumberLong(0), "syncingTo" : "mongo1.smartsitecore.com:27017", "configVersion" : 3 }, { "_id" : 2, "name" : "mongo3.smartsitecore.com:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 6902240, "configVersion" : 3, "self" : true } ], "ok" : 1 } rs0 :PRIMARY> |
We can now turn of mongod on Primary or Secondary data storage and observe what happens to replicate set using rs.status(). If Primary is down, Arbiter will automatically promote Secondary to become Primary.
Configure Sitecore to use MongoDB replica set
Finally we can update default Sitecore connection strings to point to replica set:
1 2 3 4 |
<add name="analytics" connectionString="mongodb://mongo1.smartsitecore.com:27017,mongo2.smartsitecore.com:27017/analytics?replicaSet=rs0" /> <add name="tracking.live" connectionString="mongodb://mongo1.smartsitecore.com:27017,mongo2.smartsitecore.com:27017/tracking_live?replicaSet=rs0" /> <add name="tracking.history" connectionString="mongodb://mongo1.smartsitecore.com:27017,mongo2.smartsitecore.com:27017/tracking_history?replicaSet=rs0" /> <add name="tracking.contact" connectionString="mongodb://mongo1.smartsitecore.com:27017,mongo2.smartsitecore.com:27017/tracking_contact?replicaSet=rs0" /> |
This setup guarantee improved performance and automatic failover. Data is synchronized automatically between Primary and Secondary MongoDB instances.