Local environment for Mongodb sharding
The purpose of this topic was to setup locally a MongoDB shard,
with 2 shards and then run various commands to check the actual behaviour of this system.
Environment Setup
Sharding Setup
DB Setup
Playing around
Configuring zones
Setup
The setup will have.
- 2 replicasets, each with one primary and 2 secondaries.
- 2 routers.
- 3 config server.
-
docker-compose.yaml
version: '3'
services:
# replica set 1
mongors1n1:
container_name: mongors1n1
image: mongo
command: mongod --shardsvr --replSet mongors1 --dbpath /data/db --port 27017
ports:
- 27017:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data1:/data/db
mongors1n2:
container_name: mongors1n2
image: mongo
command: mongod --shardsvr --replSet mongors1 --dbpath /data/db --port 27017
ports:
- 27027:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data2:/data/db
mongors1n3:
container_name: mongors1n3
image: mongo
command: mongod --shardsvr --replSet mongors1 --dbpath /data/db --port 27017
ports:
- 27037:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data3:/data/db
# replica set 2
mongors2n1:
container_name: mongors2n1
image: mongo
command: mongod --shardsvr --replSet mongors2 --dbpath /data/db --port 27017
ports:
- 27047:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data4:/data/db
mongors2n2:
container_name: mongors2n2
image: mongo
command: mongod --shardsvr --replSet mongors2 --dbpath /data/db --port 27017
ports:
- 27057:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data5:/data/db
mongors2n3:
container_name: mongors2n3
image: mongo
command: mongod --shardsvr --replSet mongors2 --dbpath /data/db --port 27017
ports:
- 27067:27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/data6:/data/db
# mongo config server
mongocfg1:
container_name: mongocfg1
image: mongo
command: mongod --configsvr --replSet mongors1conf --dbpath /data/db --port 27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/config1:/data/db
mongocfg2:
container_name: mongocfg2
image: mongo
command: mongod --configsvr --replSet mongors1conf --dbpath /data/db --port 27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/config2:/data/db
mongocfg3:
container_name: mongocfg3
image: mongo
command: mongod --configsvr --replSet mongors1conf --dbpath /data/db --port 27017
expose:
- "27017"
volumes:
- ~/mongo_cluster/config3:/data/db
# mongos router
mongos1:
container_name: mongos1
image: mongo
depends_on:
- mongocfg1
- mongocfg2
command: mongos --configdb mongors1conf/mongocfg1:27017,mongocfg2:27017,mongocfg3:27017 --port 27017
ports:
- 27019:27017
expose:
- "27017"
mongos2:
container_name: mongos2
image: mongo
depends_on:
- mongocfg1
- mongocfg2
command: mongos --configdb mongors1conf/mongocfg1:27017,mongocfg2:27017,mongocfg3:27017 --port 27017
ports:
- 27020:27017
expose:
- "27017"
$ docker-compose up
Sharding Setup
$ docker exec -it mongocfg1 bash -c "echo 'rs.initiate({_id: "mongors1conf",configsvr: true, members: [{ _id : 0, host : "mongocfg1" },{ _id : 1, host : "mongocfg2" }, { _id : 2, host : "mongocfg3" }]})' | mongo"
# building replica shard
$ docker exec -it mongors1n1 bash -c "echo 'rs.initiate({_id : "mongors1", members: [{ _id : 0, host : "mongors1n1" },{ _id : 1, host : "mongors1n2" },{ _id : 2, host : "mongors1n3" }]})' | mongo"
$ docker exec -it mongors2n1 bash -c "echo 'rs.initiate({_id : "mongors2", members: [{ _id : 0, host : "mongors2n1" },{ _id : 1, host : "mongors2n2" },{ _id : 2, host : "mongors2n3" }]})' | mongo"
# we add shard to the routers
$ docker exec -it mongos1 bash -c "echo 'sh.addShard("mongors1/mongors1n1")' | mongo "
$ docker exec -it mongos1 bash -c "echo 'sh.addShard("mongors2/mongors2n1")' | mongo "
DB Setup
$ docker exec -it mongors1n1 bash -c "echo 'use testDb' | mongo"
$ docker exec -it mongors1n1 bash -c "echo 'db.createCollection(\"testDb.testCollection\")' | mongo "
$ docker exec -it mongos1 bash -c "echo 'sh.shardCollection(\"testDb.testCollection\", {\"shardingField\" : 1})' | mongo "
Playing around
#login to mongos1 (router)
$ docker exec -it mongos1 mongo
#force split chunks by sharding key value.
mongos> sh.splitAt('testDb.testCollection', {shardingField: 100});
mongos> db.testCollection.insertOne({shardingField: 55});
mongos> db.testCollection.insertOne({shardingField: 155});
#now we have 2 shards, each storing one chunk with 1 document
mongos> db.testCollection.insertOne({shardingField: 55})
{
"acknowledged" : true,
"insertedId" : ObjectId("61150783c8a0ff22b82d5ae6")
}
mongos> db.testCollection.insertOne({shardingField: 155})
{
"acknowledged" : true,
"insertedId" : ObjectId("61150788c8a0ff22b82d5ae7")
}
mongos> db.testCollection.getShardDistribution();
Shard mongors2 at mongors2/mongors2n1:27017,mongors2n2:27017,mongors2n3:27017
data : 45B docs : 1 chunks : 1
estimated data per chunk : 45B
estimated docs per chunk : 1
Shard mongors1 at mongors1/mongors1n1:27017,mongors1n2:27017,mongors1n3:27017
data : 45B docs : 1 chunks : 1
estimated data per chunk : 45B
estimated docs per chunk : 1
Totals
data : 90B docs : 2 chunks : 2
Shard mongors2 contains 50% data, 50% docs in cluster, avg obj size on shard : 45B
Shard mongors1 contains 50% data, 50% docs in cluster, avg obj size on shard : 45B
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("6114bba388d545c510cfd551")
}
shards:
{ "_id" : "mongors1", "host" : "mongors1/mongors1n1:27017,mongors1n2:27017,mongors1n3:27017", "state" : 1, "topologyTime" : Timestamp(1628749545, 2) }
{ "_id" : "mongors2", "host" : "mongors2/mongors2n1:27017,mongors2n2:27017,mongors2n3:27017", "state" : 1, "topologyTime" : Timestamp(1628757106, 1) }
................
{ "_id" : "testDb", "primary" : "mongors1", "partitioned" : true, "version" : { ...... }
testDb.testCollection
shard key: { "shardingField" : 1 }
unique: false
balancing: true
chunks:
mongors1 1
mongors2 1
{ "shardingField" : { "$minKey" : 1 } } -->> { "shardingField" : 100 } on : mongors2 Timestamp(2, 0)
{ "shardingField" : 100 } -->> { "shardingField" : { "$maxKey" : 1 } } on : mongors1 Timestamp(2, 1)
mongos> db.testCollection.find({});
{ "_id" : ObjectId("61150783c8a0ff22b82d5ae6"), "shardingField" : 55 }
{ "_id" : ObjectId("61150788c8a0ff22b82d5ae7"), "shardingField" : 155 }
# connect to one replica to verify what is stored (not recommended, just for testing purposes)
$ docker exec -it mongors1n1 mongo
mongors1:PRIMARY> use testDb
switched to db testDb
mongors1:PRIMARY> db.testCollection.find({})
{ "_id" : ObjectId("61150788c8a0ff22b82d5ae7"), "shardingField" : 155 }
# connect to the other replicaset
$ docker exec -it mongors2n1 mongo
mongors2:PRIMARY> use testDb
switched to db testDb
mongors2:PRIMARY> db.testCollection.find({})
{ "_id" : ObjectId("61150783c8a0ff22b82d5ae6"), "shardingField" : 55 }
Configuring Zones
mongos> sh.addShardToZone("mongors1", "testZone")
mongos> sh.addShardToZone("mongors2", "testZone")
mongos> sh.updateZoneKeyRange("testDb.testCollection", { shardingField: 20 }, { shardingField: 120 }, "testZone")
mongos> sh.status()
--- Sharding Status ---
..................
shards:
{ "_id" : "mongors1", "host" : "mongors1/mongors1n1:27017,mongors1n2:27017,mongors1n3:27017", "state" : 1, "topologyTime" : Timestamp(1628749545, 2), "tags" : [ "testZone" ] }
{ "_id" : "mongors2", "host" : "mongors2/mongors2n1:27017,mongors2n2:27017,mongors2n3:27017", "state" : 1, "topologyTime" : Timestamp(1628757106, 1), "tags" : [ "testZone" ] }
.................
databases:
.................
{ "_id" : "testDb", "primary" : "mongors1", "partitioned" : true, "version" : { "uuid" : UUID("f1635ad8-d9b4-4ce6-9e3f-cef945fac96a"), "timestamp" : Timestamp(1628749617, 1), "lastMod" : 1 } }
testDb.testCollection
shard key: { "shardingField" : 1 }
unique: false
balancing: true
chunks:
mongors1 2
mongors2 2
{ "shardingField" : { "$minKey" : 1 } } -->> { "shardingField" : 20 } on : mongors2 Timestamp(2, 2)
{ "shardingField" : 20 } -->> { "shardingField" : 100 } on : mongors2 Timestamp(2, 3)
{ "shardingField" : 100 } -->> { "shardingField" : 120 } on : mongors1 Timestamp(2, 4)
{ "shardingField" : 120 } -->> { "shardingField" : { "$maxKey" : 1 } } on : mongors1 Timestamp(2, 5)
tag: testZone { "shardingField" : 20 } -->> { "shardingField" : 120 }