MongoDB replica set + sharding setup
Symptom
Goal: set up a replica set with automatic failover for MongoDB and extend it to a sharded cluster for horizontal scaling.
1. Start the mongod processes with the same replSet name
Start each replica set member with the same --replSet name and a reachable --bind_ip. In production, internal authentication with a keyFile or TLS is recommended. Aim for an odd number of voting members for a clear majority.
MongoDB
mongod --replSet rs0 --port 27017 --dbpath /data/n1 --bind_ip localhost,10.0.0.11
mongod --replSet rs0 --port 27017 --dbpath /data/n2 --bind_ip localhost,10.0.0.12
mongod --replSet rs0 --port 27017 --dbpath /data/n3 --bind_ip localhost,10.0.0.132. Initiate the replica set
Connect to one member with mongosh, call rs.initiate(), and define all members. This triggers the first election and a primary is chosen. Verify PRIMARY/SECONDARY roles with rs.status().
MongoDB
rs.initiate({
_id: 'rs0',
members: [
{ _id: 0, host: '10.0.0.11:27017' },
{ _id: 1, host: '10.0.0.12:27017' },
{ _id: 2, host: '10.0.0.13:27017' }
]
})
rs.status()3. Add members, set priorities and an arbiter if needed
Add members later with rs.add(). priority determines which member tends to become primary (0 = never becomes primary). An arbiter only votes and holds no data; it is used as a tie-breaker with an even number of data nodes, but a real member is preferred for data safety. In arbiter-based topologies (especially PSA), majority write concern cannot be satisfied when a data node goes down and writes wait; on 5.0+ the cluster-wide default write concern may need to be set explicitly with setDefaultRWConcern before adding an arbiter.
MongoDB
rs.add({ host: '10.0.0.14:27017', priority: 0.5 })
// Arbiter only if really needed (a data-bearing member is preferred):
rs.addArb('10.0.0.15:27017')
// change priority:
cfg = rs.conf(); cfg.members[0].priority = 2; rs.reconfig(cfg)4. Set up the config server replica set for sharding
The sharded cluster's metadata is kept in a config server replica set (--configsvr). It is itself initiated as a replica set; 3 members are recommended for high availability.
MongoDB
mongod --configsvr --replSet cfgrs --port 27019 --dbpath /data/cfg1 --bind_ip localhost,10.0.0.21
-- mongosh (on the config server):
rs.initiate({ _id: 'cfgrs', configsvr: true, members: [
{ _id: 0, host: '10.0.0.21:27019' },
{ _id: 1, host: '10.0.0.22:27019' },
{ _id: 2, host: '10.0.0.23:27019' } ] })5. Start the shard replica sets and the mongos router
Each shard is its own replica set started with --shardsvr (data durability comes from intra-shard replication). The mongos router is started pointing at the config servers; applications connect to mongos.
MongoDB
mongod --shardsvr --replSet shard1rs --port 27018 --dbpath /data/s1 --bind_ip localhost,10.0.0.31
# initiate shard1rs with rs.initiate, then mongos:
mongos --configdb cfgrs/10.0.0.21:27019,10.0.0.22:27019,10.0.0.23:27019 --port 27017 --bind_ip localhost,10.0.0.406. Add the shards and shard the collection
Connect to mongos and add each shard replica set with sh.addShard(). Enable sharding on the database and distribute the collection by a shard key with sh.shardCollection(). Key choice is critical: it should have high cardinality and an even distribution. Monitor chunk distribution with sh.status().
MongoDB
sh.addShard('shard1rs/10.0.0.31:27018')
sh.addShard('shard2rs/10.0.0.32:27018')
sh.enableSharding('appdb')
sh.shardCollection('appdb.events', { customer_id: 'hashed' })
sh.status()