Skip to content

Instantly share code, notes, and snippets.

@anushshukla
Created July 13, 2022 02:33
Show Gist options
  • Select an option

  • Save anushshukla/bd0afd633d669afb99865a82e8b7dd5f to your computer and use it in GitHub Desktop.

Select an option

Save anushshukla/bd0afd633d669afb99865a82e8b7dd5f to your computer and use it in GitHub Desktop.
Mongo Replica Set Guidelines

Why do we need it?

Adding replicas in Mongo helps us achieve high scalability and availability.

How do we setup it?

We can add secondary nodes and arbiters (for primary election purpose only) if required.

What is the possible best setup?

Best recommendation is to start with https://docs.mongodb.com/manual/core/replica-set-architecture-three-members.

At the application, connection string needs to updated with other nodes host and port while setting the readPreference=secondayPreferred. (citing Read Preference) while having readConcern=majority (citing Read Concern).

What are the drawbacks?

As mongo replication is like a distributed system and one of the major concern is concurrency handling arising due to race condition where same resource is being modified after being fetched which may occur due to high concurrent traffic

How to prevent concurrency issues?

For avoiding concurrent issues, the ODM library (Mongoose) being used as the project dependency in the API of the backend application layer (Nodejs) provides a method to fetch the query from primary (master) node instead of secondary (slave). Otherwise there is way to simulate lock mode in Mongo while reading data. (please refer How To SELECT ... FOR UPDATE inside MongoDB Transactions | MongoDB Blog ).

Library Documentation

Considering the version of the ODM library, please refer Mongoose v6.4.4: API docs for find query operations while Mongoose v6.4.4: API docs for aggregation of piped queries. Alternatively, Mongoose v6.4.4: API docs can be used for fetching for data persistence.

Below is a relevant example.

Read from primary

production.user.find(
  {
    email: 'god@heaven.com'
  },
  {
    _id: 1
  }
).read('primary');

Read in lock mode (simulation)

production.user.findOneAndUpdate({ _id: 1 },
     { $set: { lockField: { lockName: "concurrent-registration", pseudoRandom: ObjectId() } } })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment