Last active
August 29, 2015 14:03
-
-
Save saintc0d3r/417b3b9fa492cdfdd454 to your computer and use it in GitHub Desktop.
[MongoDB] Creating a replica set ( a group of 3 or more mongod servers that behaves like RAID-1 disks) in a local machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTES: Adjust replSet, dbpath, port parameters as you see them fit on your system environments. | |
# Creates data directories for 3 mongod servers | |
mkdir -p /data/rs1 /data/rs2 /data/rs3 | |
# Creates 3 mongod servers in local machine | |
mongod --replSet rs1 --logpath "node-1.log" --dbpath /data/rs1 --port 27018 --fork | |
mongod --replSet rs1 --logpath "node-2.log" --dbpath /data/rs2 --port 27019 --fork | |
mongod --replSet rs1 --logpath "node-3.log" --dbpath /data/rs3 --port 27020 --fork | |
#start replica set initialisation's script on the 2nd node, the primary node | |
mongo --port 27019 < init_replica_sets.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Run this script to configure & initialise a running replica set | |
*/ | |
// Config's parameteres - Adjust them as you see it fit to your needs. | |
var replica_set_id = "rs1"; | |
// var hosts = ['SERVER_A', 'SERVER_B', 'SERVER_C']; | |
var hosts = ['127.0.0.1','127.0.0.1','127.0.0.1']; | |
var ports = ['27018','27019','27020']; | |
// Build the replica set's config | |
var config = { | |
_id: replica_set_id, | |
members: [] | |
} | |
// Configure the participating nodes in the replica set | |
for(var i=0; i<hosts.length; i++){ | |
config.members[i] = { _id: i, 'host': hosts[i]+ports[i] } | |
} | |
// Determine which node that is not allowed to be Primary Node when one of other nodes (in the replica set) is failing. | |
// We'll pick 1st node as the voter node. | |
config.members[0].priority = 0; | |
// For the node whose priority has been set as 0, determine amount of delay before this node gets latest version of data from the other nodes in the replica set. | |
config.members[0].slaveDelay = 5; // 5 seconds delay | |
// Print the confiig object on the console (Comment this if you don't want to see it on screen ) | |
printjson(config); | |
// Start the initialisation | |
rs.initiate(config); | |
// Show replica set's status after initialisation | |
rs.status(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HOW TO - Run the scripts: | |
------------------------- | |
1. Place these 2 scripts in a same directory. | |
2. Change the bash script file's attribute so that it become executable. Example: | |
chmod 755 01_create_replica_set.sh | |
3. Run the bash script file. | |
./01_create_replica_set.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Testing the replica set: | |
======================== | |
I. Functional Tests: | |
--------------------- | |
1. Connect to 2nd node (the Primary Node) by invoking this command (supposed, the primary node's port is 27019): | |
mongo --host 127.0.0.1 --port 27019 | |
2. Confirm that the mongo prompt is shown like this: | |
rs1:PRIMARY> _ | |
3. On the mongo prompt, run this command to display the current status of the replica set: | |
rs.status() | |
4. Add a new db & insert a new document into the db's collection. Example: | |
use restaurant | |
db.menus.insert({'name':'fried rice', 'price': 1.5}) | |
5. Open a new terminal window | |
6. In the new terimnal window, connect to the 3rd node ( the secondary node) by invoking this command (supposed, the secondary node's port is 27020): | |
mongo --host 127.0.0.1 --port 27020 | |
7. Confirm that the new db created in Primary Node has been in there: | |
show dbs | |
8. Use the new db and query the created document as in the following example: | |
use restaurant | |
db.menus.findOne() | |
9. Confirm that similar error is returned: | |
2014-07-12T15:58:41.799+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131 | |
10. On the mongo prompt, run thirs.statuss command to sync this node with the primary node: | |
rs.slaveOk() | |
11. Repeat step #8. Confirm that the query returns result now. | |
12. On the secondary node, try add a new document. Example: | |
db.menus.insert({'name': 'chicken porridge', 'price': 2.0}) | |
13. Confirm that the document insertion is failing and return this similar error: | |
WriteResult({ "writeError" : { "code" : undefined, "errmsg" : "not master" } }) | |
The error happens because we could not insert any new documents into Secondary node. We could only read data from it. | |
II. Fault-tolerant test: | |
------------------------- | |
1. Open the log file that's belong to the primary node (e.g. node-2.log) using test editor application. | |
2. Notice the 1st line in the opened log file. Make note the pid number (e.g. pid=19736). | |
3. Bring down that primary node by killing its process by pid. Example: | |
kill 19736 | |
4. Go back to the terminal window that run mongo on Primary Node and check the current status: | |
rs.status() | |
Confirm that the prior Primary node's stateStr = "(not reachable/healthy)" & the other node has been elected as the new Primary Node. | |
5. Connect to the new Primary Node: | |
mongo --host 127.0.0.1 --port 27020 | |
6. On the Primary Node's mongo shell, add a new document. Example: | |
db.menus.insert({'name': 'chicken porridge', 'price': 2.0}) | |
Confirm that the new document insertion is success. | |
7. Go to the other running Secondary Node's terminal window mongo shell and query the collection. Example: | |
rs.slaveOk() | |
db.menus.find() | |
Confirm that the new document inserted in step #6 is included in the query's result. | |
8. Start the killed node in the step #3. Example: | |
mongod --replSet rs1 --logpath "node-2.log" --dbpath /data/rs2 --port 27019 --fork | |
9. Connect to the re-started node & check the status: | |
rs.status() | |
Confirm that the restarted node is assigned as a secondary node. | |
10. On the node's mongo shell stated in step #9, query the document. Example: | |
rs.slaveOk() | |
use restaurant | |
db.menus.find() | |
Confirm that the query returned consistent result as in the other nodes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTES: Adjust replSet, dbpath, port parameters as you see them fit on your system environments. | |
# Creates data directories for 3 mongod servers (rs_01, rs_02, rs_03) | |
rm -rf *.log | |
#rm -rf /data/rs1 /data/rs2 /data/rs3 | |
mkdir -p ~/MongoDatabase/Dev/rs01 ~/MongoDatabase/Dev/rs02 ~/MongoDatabase/Dev/rs03 | |
# Creates 3 mongod servers rs_01, rs_02, rs_03 | |
mongod --replSet devrs --logpath "1.log" --dbpath ~/MongoDatabase/Dev/rs01 --port 27017 --smallfiles --oplogSize 64 --fork | |
mongod --replSet devrs --logpath "2.log" --dbpath ~/MongoDatabase/Dev/rs02 --port 27018 --smallfiles --oplogSize 64 --fork | |
mongod --replSet devrs --logpath "3.log" --dbpath ~/MongoDatabase/Dev/rs03 --port 27019 --smallfiles --oplogSize 64 --fork | |
sleep 5 | |
# Connect to one server node and initiate the replica set m101 | |
mongo --port 27017 << 'EOF' | |
config = { | |
_id: "devrs", | |
members: [ | |
{_id:0, host: "localhost:27017"}, | |
{_id:1, host: "localhost:27018"}, | |
{_id:2, host: "localhost:27019"} | |
] | |
}; | |
rs.initiate(config) | |
rs.status | |
EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment