
MongoDB Cookbook - Second Edition
By :

In the previous recipe, we started a replica set of three mongod processes. In this recipe, we will work with this setup by connecting to it using the mongo client application, perform queries, insert data, and take a look at some of the interesting aspects of a replica set from a client's perspective.
The prerequisite for this recipe is that the replica set should be set up and running. Refer to the previous recipe, Starting multiple instances as part of a replica set, for details on how to start the replica set.
PRIMARY
and one for SECONDARY
. Execute the following command on the command prompt:> mongo localhost:27000
PRIMARY
or SECONDARY
. It should show the replica set's name followed by a :
, followed by the server state. In this case, if the replica set is initialized, up, and running, we should see either repSetTest:PRIMARY>
or repSetTest:SECONDARY>
.rs.status()
command in the shell and look out for the stateStr
field. This should give us the primary server. Use the mongo shell to connect to this server.repSetTest:PRIMARY> db.replTest.insert({_id:1, value:'abc'})
repSetTest:PRIMARY> db.replTest.findOne() { "_id" : 1, "value" : "abc" }
SECONDARY
node and execute the following:repSetTest:SECONDARY> db.replTest.findOne()
On doing this, we should see the following error on the console:
{ "$err" : "not master and slaveOk=false", "code" : 13435 }
repSetTest:SECONDARY> rs.slaveOk(true)
repSetTest:SECONDARY>db.replTest.findOne() { "_id" : 1, "value" : "abc" }
repSetTest:SECONDARY> db.replTest.insert({_id:1, value:'abc'}) not master
We have done a lot of things in this recipe, and we will try to throw some light on some of the important concepts to remember.
We basically connect to a primary and secondary node from the shell and perform (I would say, try to perform) selects and inserts. The architecture of a Mongo replica set is made of one primary (just one, no more, no less) and multiple secondary nodes. All writes happen on the PRIMARY
only. Note that replication is not a mechanism to distribute the read request load that enables scaling the system. Its primary intent is to ensure high availability of data. By default, we are not permitted to read data from the secondary nodes. In step 6, we simply insert data from the primary node and then execute a query to get the document that we inserted. This is straightforward and nothing related to clustering here. Just note that we inserted the document from the primary and then queried it back.
In the next step, we execute the same query but this time, from the secondary's shell. By default, querying is not enabled on the SECONDARY
. There might be a small lag in replicating the data possibly due to heavy data volumes to be replicated, network latency, or hardware capacity to name a few of the causes, and thus, querying on the secondary might not reflect the latest inserts or updates made on the primary. However, if we are ok with it and can live with the slight lag in the data being replicated, all we need to do is enable querying on the SECONDARY
node explicitly by just executing one command, rs.slaveOk()
or rs.slaveOk(true)
. Once this is done, we are free to execute queries on the secondary nodes too.
Finally, we try to insert the data into a collection of the slave node. Under no circumstances is this permitted, regardless of whether we have done rs.slaveOk()
. When rs.slaveOk()
is invoked, it just permits the data to be queried from the SECONDARY
node. All write operations still have to go to the primary and then flow down to the secondary. The internals of replication will be covered in a different recipe in the administration section.
The next recipe, Connecting to the replica set to query and insert data from a Java client, is about connecting to a replica set from a Java client.
Change the font size
Change margin width
Change background colour