Setting up a replica set in MongoDB
Tags: replication, mongodb
Published: 2017-08-15 15:51:04

---
title: Setting up a replica set in MongoDB
published: true
description: A closer look at replication in MongoDB
tags: replication, mongodb,
canonical_url: https://www.damiencosset.com/setting-replica-set-mongodb/
---

## Introduction

If you open up your terminal and launch a *mongod* instance,without any options, you are using a *standalone server*. There is one copy of your data. It's an quick and easy way to get started but it's extremely dangerous in a production environment.

A server crash could make your data unavailable. Hardware issues could force you to move your data. Replication keeps several identical copies of your data on multiple servers. If something happens to one of your servers, you have another one ready to take its place and keep your application running and your data safe.

In MongoDB, replication is achieved by creating a *replica set*. A *replica set* is composed of multiple servers. One of them is defined as the *primary*. This is the server taking client requests. The other servers are called *secondaries*. They have a copy of your primary's data. Your primary goes down, one of the secondaries becomes the primary, and your data is still available.

## Setting up a replica set

First, let's create three data directories for each node. Open up a terminal window and type:

`mkdir -p ~/data/rs{1,2,3}`

Or this on Windows:

`md c:\data\rs1 c:\data\rs2 c:\data\rs3`

Next, run the following commands in three different terminal windows:

```bash
mongod --replSet introRep --dbpath ~/data/rs1 --port 27017 
mongod --replSet introRep --dbpath ~/data/rs2 --port 27018 
mongod --replSet introRep --dbpath ~/data/rs3 --port 27019 
```

*Note:* Replace *~/data/rs1* with *c:\data\rs1* on Windows. Same for the other two.

Let's decompose these commands:

We create three different mongod instances.

- --replSet <replicaSetName> 

We are saying to our mongod instance that it is part of a replica set. Each host in the same replica set must have the same set name. Here, I chose *introRep*

- --dbpath <path>

Defines where this mongod instance will store its data. We created those directories earlier. Each set is assigned a different directory.

- --port <port>

Self explanatory, the sets can't run on the same port. 27017 is the default port for mongod. I use 27018 and 27019 for the other two.

Great, now you have three separate *mongod* processes running.

## Configuration

At this point, our mongod processes do not know about each other. We need to create a configuration with the list of each of the members of our replica set and inform on of our mongod processes.

Open up a new terminal window and connect to one of the mongod processes by specifying a port:

`mongo --port 27017`

Next, we'll create a configuration document. The document will have two keys:

- **_id** : Name of the replica set. For our example, *introRep*

- **members**: Array of documents. Each document has an *_id* key and a *host* key. It represents every set in our replica set.

Here is how it will look:

```
config = {
... _id: "introRep",
... members: [
... {_id: 0, host: "localhost:27017"},
... {_id: 1, host: "localhost:27018"},
... {_id: 2, host: "localhost:27019"}
... ]}
{
```

Store this in a variable and pass it to the *rs.initiate()* method to initiate a replica set:

`rs.initiate(config)`

Great, *localhost:27017* will notify the other members of the new configuration. After that, they will elect a primary.

## Replica set status

Your replica set is now fully functional. If you launch all three sets with mongo and the appropriate --port flag, you will see one prefixed with *introRep>PRIMARY>*, the other two will have *introRep>SECONDARY>* as prefix. 

To have more information about your replica set, you can use the *rs.status()* helper:

```
introRep:PRIMARY> rs.status()
{
	"set" : "introRep",
	"date" : ISODate("2017-08-15T15:37:14.734Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1502811433, 1),
			"t" : NumberLong(1)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1502811433, 1),
			"t" : NumberLong(1)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1502811433, 1),
			"t" : NumberLong(1)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "localhost:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 949,
			"optime" : {
				"ts" : Timestamp(1502811433, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-08-15T15:37:13Z"),
			"electionTime" : Timestamp(1502810832, 1),
			"electionDate" : ISODate("2017-08-15T15:27:12Z"),
			"configVersion" : 1,
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "localhost:27018",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 613,
			"optime" : {
				"ts" : Timestamp(1502811433, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1502811433, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-08-15T15:37:13Z"),
			"optimeDurableDate" : ISODate("2017-08-15T15:37:13Z"),
			"lastHeartbeat" : ISODate("2017-08-15T15:37:13.925Z"),
			"lastHeartbeatRecv" : ISODate("2017-08-15T15:37:14.472Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "localhost:27017",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "localhost:27019",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 613,
			"optime" : {
				"ts" : Timestamp(1502811433, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1502811433, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-08-15T15:37:13Z"),
			"optimeDurableDate" : ISODate("2017-08-15T15:37:13Z"),
			"lastHeartbeat" : ISODate("2017-08-15T15:37:13.925Z"),
			"lastHeartbeatRecv" : ISODate("2017-08-15T15:37:14.559Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "localhost:27018",
			"configVersion" : 1
		}
	],
	"ok" : 1
}
```

If you look in the members array, you will see our three sets listed. On my machine, *localhost:27017* has been elected primary. We can see this with the *stateStr* set to *PRIMARY*. The other two are set to *SECONDARY*.

Congratulations! Your successfully set up a replica set with MongoDB!!

Source: <a href='http://shop.oreilly.com/product/0636920049531.do' target='_blank'>MongoDB: The Definitive Guide, 3rd Edition</a>