Skip to content

Instantly share code, notes, and snippets.

@joeytwiddle
Last active August 31, 2023 16:51
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save joeytwiddle/34c9b48517004efce0545f8e07388c9f to your computer and use it in GitHub Desktop.
Save joeytwiddle/34c9b48517004efce0545f8e07388c9f to your computer and use it in GitHub Desktop.
Script to start a mongodb cluster with three shards, for MongoDB 3.4
#!/usr/bin/env bash
set -e
# This script will start three shards, a config server and a mongos, all on the current machine.
#
# It was written for Mongo 3.4, based on https://docs.mongodb.com/manual/tutorial/deploy-shard-cluster/
#
# This script is only for testing purposes. In production, you would run each of these servers on a different machine.
#
# If you do run this, please ensure that your machine has a few gigs of swap space. mongod indexes will happily
# gobble all the main memory, so more than one mongod may make your machine unresponsive without swap.
#
# The first time you run it, pass this variable for the initial setup:
#
# FIRST_TIME=1 bash ./startShardedCluster.sh
#
# In future you can just start the servers like this:
#
# bash ./startShardedCluster.sh
#
# To stop them:
#
# killall mongod mongos
# For performance reasons, this script only creates one replica for each replicaset.
# But if you want each shard to have two replicas inside it, you can uncomment some of the lines below.
# The lines to uncomment are: the expected_count, 3 x mkdir, and 3 x mongod
# You should also swap the 3 x rs.initiate() lines for rs0, rs1 and rs2: we need the lines with 2 replicaset members instead of 1.
expected_count=5
#expected_count=8
cd "$(dirname $0)"
local_ip="$(/sbin/ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | tr -d "addr:" | head -n 1)"
mkdir -p log
mkdir -p dbData/configdb
mkdir -p dbData/db0-0
#mkdir -p dbData/db0-1
mkdir -p dbData/db1-0
#mkdir -p dbData/db1-1
mkdir -p dbData/db2-0
#mkdir -p dbData/db2-1
pkill -u $UID mongod || true
pkill -u $UID mongos || true
sleep 1
# Start config server
# We should have 3 or more of these, but we only have one
mongod --configsvr --replSet csrs0 --dbpath dbData/configdb --port 27018 --fork --logpath log/mongods.log
if [ -n "$FIRST_TIME" ]
then
# Initialise the config server
# If we had multiple config servers, they should all be listed in the members array
mongo localhost:27018 << !
rs.initiate({_id: "csrs0", configsvr: true, members: [{_id: 0, host: "${local_ip}:27018"}]});
!
fi
# Start mongodb servers for rs0
mongod --port 27020 --dbpath dbData/db0-0 --shardsvr --replSet rs0 --fork --logpath log/mongod0-0.log
#mongod --port 27021 --dbpath dbData/db0-1 --shardsvr --replSet rs0 --fork --logpath log/mongod0-1.log
# Start mongodb servers for rs1
mongod --port 27030 --dbpath dbData/db1-0 --shardsvr --replSet rs1 --fork --logpath log/mongod1-0.log
#mongod --port 27031 --dbpath dbData/db1-1 --shardsvr --replSet rs1 --fork --logpath log/mongod1-1.log
# Start mongodb servers for rs3
mongod --port 27040 --dbpath dbData/db2-0 --shardsvr --replSet rs2 --fork --logpath log/mongod2-0.log
#mongod --port 27041 --dbpath dbData/db2-1 --shardsvr --replSet rs2 --fork --logpath log/mongod2-1.log
if [ -n "$FIRST_TIME" ]
then
# Set up the replicasets
mongo localhost:27020 << !
rs.initiate({_id: "rs0", members: [{_id: 0, host: "${local_ip}:27020"}]});
//rs.initiate({_id: "rs0", members: [{_id: 0, host: "${local_ip}:27020"}, {_id: 1, host: "${local_ip}:27021"}]});
!
mongo localhost:27030 << !
rs.initiate({_id: "rs1", members: [{_id: 0, host: "${local_ip}:27030"}]});
//rs.initiate({_id: "rs1", members: [{_id: 0, host: "${local_ip}:27030"}, {_id: 1, host: "${local_ip}:27031"}]});
!
mongo localhost:27040 << !
rs.initiate({_id: "rs2", members: [{_id: 0, host: "${local_ip}:27040"}]});
//rs.initiate({_id: "rs2", members: [{_id: 0, host: "${local_ip}:27040"}, {_id: 1, host: "${local_ip}:27041"}]});
!
fi
# mongos will complain if it cannot connect to :27018, but we don't need to wait now that we have started the config server first
#sleep 5
# If we had multiple config servers, we would add them all to the string below, separated by ','s
mongos --configdb "csrs0/${local_ip}:27018" --port 27017 --fork --logpath log/mongos.log
# I tried bringing all the FIRST_TIME config down here, into one place, but that did not work!
# The mongos keps saying "No primary detected for set csrs0"
if [ -n "$FIRST_TIME" ]
then
# Connect to the mongos and add shards
mongo localhost:27017 << !
sh.addShard("rs0/${local_ip}:27020");
sh.addShard("rs1/${local_ip}:27030");
sh.addShard("rs2/${local_ip}:27040");
sh.enableSharding("FishGameDB");
!
fi
# Now everything should be ready. The final step is to actually shard some collections:
# sh.shardCollection("<database>.<collection>", { <key> : <direction> } )
echo "============================="
ps aux | grep " mongo[ds] "
process_count="$(ps aux | grep " mongo[ds] " | wc -l)"
if [ "$process_count" = "$expected_count" ]
then echo "Started OK"
else
echo "ERROR: We need $expected_count DB processes to be running. Please try re-running the script." >&2
exit 1
fi
@joeytwiddle
Copy link
Author

joeytwiddle commented Jan 4, 2018

This script was inspired by: https://gist.github.com/leetreveil/7233677

@burbabull
Copy link

Thanks!

@jeasonchan
Copy link

thx!

@linydquantil
Copy link

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment