Sitecore xDB - setting up xDB and Mongo replication in production
Recently I set up xDB for a client of ours. I thought I'd share the experience and some Mongo knowledge I've picked up from the MongoDb for DBAs course.
The first thing to mention is fairly obvious - please read the guides Sitecore provide on the SDN before setting up xDB, my experiences may differ from yours.
Infrastructure
So the first thing to consider is our infrastructure. We choose to use three equally high performant Windows servers each hosting a MongoDb instance. One box will act as the primary (99.9% of the time Sitecore will read and write to this machine). The others will be set up as secondaries forming a replication set with the primary. When the primary recieved data it will push it to both secondaries. With Mongo we get automatic failover and automatic node recovery after failover has occurred. i.e a secondary will start accepting read/writes as it is elected to be the new primary.
Another option is two have two high spec machines and another light weight machine acting as an arbiter.
When failover occurs Mongo needs to elect a new primary - it cannot do this if there are only two machines in the replica set. An arbiter gets a vote but stores no data, it is purely used in elections.
So let's set this up.
Setting up the replica set
I'm going to go through the process on my local machine which will run three MongoD processes on different ports. On production we will have one MongoD process per server and each will use the default port.
The first thing to do is download Mongo and install on your machine. (You may need to add the mongo bin dir to your path and restart)
Next create a data directory for each of your Mongo processes. e.g C:\Mongo\xDB\1, C:\Mongo\xDB\2, C:\Mongo\xDB\3.
We need to set up three mongo processes specifying that each should be in the same replica set. To set up the first open up a new shell and type:
mongod --replSet SitecoreLocalTestSet --dbpath C:\mongo\xDB\1 --port 27001 --oplogSize 50 --smallfiles
Note: To run mongo as a windows service add --logpath=D:\mongodb\log.txt --install to the command above. This means each times the server restarts mongod process will be started.
The oplogSize command is used to keep the log small as we are in non production. smallfiles is also not needed in production.
Ok great, thats the primary mongo process set up lets create the secondaries (you will need a new shell for each):
mongod --replSet SitecoreLocalTestSet --dbpath C:\mongo\xDB\2 --port 27002 --oplogSize 50 --smallfiles
mongod --replSet SitecoreLocalTestSet --dbpath C:\mongo\xDB\3 --port 27003 --oplogSize 50 --smallfiles
Next we must initiate the replica set. Open up another shell and connect to the primary.
mongo --port 27001
type the following into the shell (Mongo uses json notation):
cfg = {
_id : "SitecoreLocalTestSet",
members :
[{ _id:0, host:"localhost:27001", priority:1 },
{ _id:1, host:"localhost:27002", priority:0.5 },
{ _id:2, host:"localhost:27003", priority:0.5 }]
}
Don't use localhost or a raw IP in production, use DNS for the hostnames.
Next type:
rs.initiate(cfg)
The replica set should come online in less than a minute.
We now have our replica set up and running. You can check it's status at any time by connecting to the primary and typing.
rs.status()
Right, let's get some data in there via Sitecore.
Setting up Sitecore and Testing
First update your three Mongo connectionstrings to the following format:
mongodb://localhost:27001,localhost:27002,localhost:27003/analytics?replicaSet=SitecoreLocalTestSet
This will ensure that if failover occurs Mongo starts talking to the newly elected primary.
Ensure your pages / layout have the Analytics tracking tag included. For MVC:
@Html.Sitecore().VisitorIdentification()
Open your website in the browser and navigate to a few pages. If you look in the source you should see sitecore's VisitorIdentification.js.
End your session, perhaps rebuild your solution to force the matter. On Session End Sitecore will push data from session to the Mongo collection database.
You can see if Mongo is set up correctly by using a GUI such as RoboMongo or just via the shell. To check via the shell:
mongo --port 27001
use analytics
db.Interactions.count()If you get a value larger than zero then success!
Testing Failover
To test failover simply kill the first MongoD process.
If you then connect to the second instance (mongo --port 27002) you should see it is marked primary.
Start a new session clicking around your website. After the session has ended you should notice the Interactions table has some new entries - if it does great Sitecore is now recognising 27002 as primary.
You can now bring 27001 back online. As it has a priority value higher than the secondaries Mongo will recover the instance and make it primary.
You can then fire more data at Mongo and ensure all three servers remain in sync.