MongoDB replica set installation on Windows
Client’s requirements:
Even number of servers (4) on two geolocations (UK and Holland) with a following priority - failover order from UK to Holland, arbiter should be installed on Azure.
Servers hostnames (for demonstration only):
uk1primary
uk2secondary
nl1secondary
nl2secondary
az1arbiter
MongoDB servers’ installations
Download MongoDB Community server 64-bit (last version, at the time of writing it’s 3.4.4) as *.msi file to each server.
On each replica set member it’s recommended to install the same version of MongoDB.
Create two folders on each server: one for MongoDB binaries and configuration file and second for MongoDB data. In the MongoDB data folder create two subfolders: one for data and another for system logs.
Create log file in the system log folder: mongod.log (as a simple text file and change it’s extention). Of course, it’s possible to do it by batch.
Create configuration file and place it in an appropriate folder (usually installation folder): mongod.cfg (as a simple text file and change it’s extention). Of course, it’s possible to do it by batch.
Configure the configuration file with necessary options and custom options you need:
systemLog:
destination: file
path: D:\data\log\mongod.log
storage:
dbPath: D:\data\db
engine: wiredTiger
net:
port: 27017 # or 30000 on arbiter only
etc.
Install MongoDB Community server through GUI or by batch with customized installation folder:
> msiexec.exe /q /i mongodb-win32-x86_64-2008plus-ssl-3.4.4-signed.msi INSTALLLOCATION="D:\MongoDB.3.4.4" ADDLOCAL="all"
Install MongoDB service before starting the server in command prompt (run as administrator):
> sc.exe create MongoDB binPath= "\"D:\MongoDB.3.4.4\bin\mongod.exe\" --service --config=\"D:\ MongoDB.3.4.4\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"
or
> "D:\MongoDB.3.4.4\bin\mongod.exe" --config "D:\MongoDB.3.4.4\mongod.cfg" --install
Start MongoDB service:
net start MongoDB
Check in Service that this service in “Running” status.
Connect to the server through command prompt:
> "C:\Program Files\MongoDB\Server\3.4\bin\mongo.exe"
Repeat steps 1-8 on each replica set server.
MongoDB replica set installation
Before starting check connectivity between servers: ping, telnet and open ports (27017 and 30000 for arbiter).
Add replica set configurations to the configuration file on each server and restart after that:
replication.replSetName: ReplicationSet_Name
replication.oplogSizeMB: <value> (at least 5% of a logical disk)
etc.
Connect to the mongo shell on the primary server and initiate replica set:
> rs.initiate({_id: "ReplicationSet_Name",version: 1,members:[{_id: 1, host : "uk1primary:27017", arbiterOnly: false, priority: 5 }]})
Check initialization:
PRIMARY> db.isMaster()
PRIMARY> rs.status()
PRIMARY> rs.conf()
Stop the primary server and secondary servers and copy data directory from primary to all secondary server (data only) than start all servers.
Check on each secondary an existing of databases: show dbs.
Add each secondary by priority order and after that an arbiter:
PRIMARY> rs.add( { _id: 2, host : "uk2secondary:27017",arbiterOnly: false, priority: 4 } )
PRIMARY> rs.add( { _id: 3, host : "nl1secondary:27017",arbiterOnly: false, priority: 3 } )
PRIMARY> rs.add( { _id: 4, host : "nl2secondary:27017",arbiterOnly: false, priority: 2 } )
PRIMARY> rs.add( { _id: 5, host : "az1arbiter:30000",arbiterOnly: true, priority: 1 } )
You can also add the arbiter by the simple query:
PRIMARY> rs.addArb( { "az1arbiter:30000" } )
Check replica set on primary server:
PRIMARY> rs.status()
PRIMARY> rs.printReplicationInfo()
PRIMARY> db.getReplicationInfo.tLast()
On secondary servers, also:
SECONDARY> rs.status()
SECONDARY> rs.slaveOk()
SECONDARY> show dbs
SECONDARY> rs.printSlaveReplicationInfo()
Remarks:
Don’t copy data directory from a primary server before you have initialized the primary as primary. At the time of adding a secondary server this server (secondary) will start to read the oplog of the primary server. Because of this log file contains transactions of replica set you will copy an empty log file actually (you haven’t initialized replica set before the copying yet). Therefore, as soon as a secondary server will start to pull transactions from the primary’s olpog it will encounter that there aren’t any flag to start from it and initiate an initial synchronization process (initial sync) - copy all data directory’s content from primary to secondary after deleting of existing databases on secondary server. If you have a large data directory it can take a lot of time and the worst scenario will be that you will not be able to synchronize a secondary server due to a big period of time - the primary server “runs” far away from the secondary.
Oplog is a capped collection and can hold data of n-hours: the larger the file is, the more transactional it will hold and allowed windows by oplog will be bigger. Follow the vendor suggestions and your workload restrictions.
Do not add an arbiter right after primary server’s initialization – add if at least one secondary server is synchronized with replica set.
Do not add an arbiter to the odd number of members – replica set can be suffer from tied elections.
Initialize replica sets’ host with hostname as possible.
In order to minimize the default creation of data on arbiter at the time of initialization, set the following in the arbiter’s configuration file:
storage.journal.enabled: false
Check the mongod.log on each server to determine heartbeat errors, unexpected failovers and other replica set issues. The log of arbiter can include more data about these issues because of its voting role.
In the next article we’ll write about MongoDB installation steps on Linux (CentOS 7).
Good luck!