Skip to content

Instantly share code, notes, and snippets.

@OndrejP
Last active August 29, 2015 14:01
Show Gist options
  • Save OndrejP/6980c07e201598e93b18 to your computer and use it in GitHub Desktop.
Save OndrejP/6980c07e201598e93b18 to your computer and use it in GitHub Desktop.
mongodb one step to build shard
#!/bin/bash
###############################################
#
# mongodb one step to build shard
#
# Easy way to build shard witch two replicaSets, three config servers and mongos.
#
# Requirments:
# - empty directory [/tmp/myShard/]
# - mongod/mongos on system
# - cca 200MB/replicaSet default 600MB to start
#
#
export BindIP=localhost
export rsParams=(0 0 "arbiterOnly : true" "priority: 2")
export numberOfRepSet=2 # min 2 (cca 200MB on disk for each)
export MongodbParams=" --oplogSize 2 --smallfiles --noprealloc --noauth --logappend --nojournal "
export MongosPortPrefix=27
export MongosPort=${MongosPortPrefix}017
function isPortFree() { netstat -ntl 2>&1 | grep ${1} | grep -q -i listen && return 1 || return 0 ;}
if [ "$1" == "destroy" ] ; then
echo "killall mongodb/mongos"
for I in $(cat *.pid); do
[ -d /proc/$I/ ] && kill -9 $I;
done
echo "remove all mdb-* mongos* repSetDone.txt"
rm -rf mdb-* mongos* repSetDone.txt
exit 0
elif [ "$1" == "create" ] ; then
# check empty directory
if [ "$(ls -1 | grep -v ${0##*/} | wc -l)" != "0" ] ; then
echo "Actual directory ($(pwd)) must be empty(like /tmp/myShard/)"
exit 2
fi
# check mongos port
if ! isPortFree ${MongosPort} ; then
echo -e "Port ${MongosPort} already usage. \nChange port or destroy other mongo."
exit 3
fi
else
echo -e "Usage: $0 [create|destroy]" 1>&2
exit 1
fi
for s in $(seq 1 ${numberOfRepSet}); do
echo "create replicaSet: $s"
sInit[$s]=$(mktemp) ;
echo "conf={ _id : \"s${s}\", members: [" >${sInit[$s]}
shAddSet[$s]="db.runCommand( { addshard : \"s${s}/"
for r in 1 2 3; do
id=mdb-s${s}r${r}
port=${MongosPortPrefix}${s}0${r}
if ! isPortFree ${port} ; then
echo -e "Port ${port} already use. \nChange port prefix or destroy other mongod instance." ;
exit 4
fi
mkdir ${id} 2>/dev/null
# update replicaSet Init file
echo -n "{_id: $r,host : \"${BindIP}:${port}\" " >>${sInit[$s]}
[ "${rsParams[$r]}" == "0" ] || echo -n ",${rsParams[$r]} " >>${sInit[$s]}
echo "}," >>${sInit[$s]}
# Update shard init
shAddSet[$s]=${shAddSet[$s]}"${BindIP}:${port},"
mongod \
${MongodbParams} \
--replSet s$s \
--dbpath ${id} \
--pidfilepath ${id}.pid \
--logpath ${id}.log \
--port ${port} \
>/dev/null &
done
# add End to shard Init
echo "] }; rs.initiate(conf) " >>${sInit[$s]}
# Remove last char from string
shAddSet[$s]=${shAddSet[$s]%,}
shAddSet[$s]=${shAddSet[$s]}"\", \"name\": \"s${s}\"} );"
sleep 1s;
# Initiate replicaSet and wait for it
echo "initiate replicaSet s${s} (wait 0-90 second)"
mongo --port ${port} < ${sInit[$s]} >/dev/null 2>/dev/null
for I in $(seq 1 30); do
mongo --quiet --port ${port} --eval "rs.isMaster().ismaster" \
| grep -q true \
&& echo "replicaSet s${s} initiated ..." \
&& echo "${id}" >>repSetDone.txt \
&& break
sleep 2s;
done &
done
touch repSetDone.txt
export ShardNum=${s}
export cfgString=''
echo "create config set"
for c in 1 2 3; do
id=mdb-cfg0${c}
port=${MongosPortPrefix}${c}2${r}
if ! isPortFree ${port} ; then
echo -e "Port ${port} already use. \nChange port prefix or destroy other mongod instance." ;
exit 5
fi
mkdir ${id} 2>/dev/null
mongod \
${MongodbParams} \
--dbpath ${id} \
--pidfilepath ${id}.pid \
--logpath ${id}.log \
--configsvr \
--port ${port} \
>/dev/null &
cfgString="${cfgString},${BindIP}:${port}"
done
cfgString=${cfgString#,*}
sleep 1s
echo "start mongos"
mongos \
--port ${MongosPort} \
--logpath mongos.log \
--logappend \
--pidfilepath mongos.pid \
--nohttpinterface \
--configdb ${cfgString} \
>/dev/null &
rsDone=$(wc -l repSetDone.txt | cut -d\ -f1)
max=20 ; x=0
# cat ${sInit[*]}
while [ "${ShardNum}" != "${rsDone}" ] ; do
echo "waiting to replicaSets (${rsDone}/$ShardNum)";
sleep 5s;
rsDone=$(wc -l repSetDone.txt | cut -d\ -f1)
if [ $x -lt $max ] ; then
let x=$x+1
else
echo "!!! Something wrong in replicaSet init. (look at ${sInit[*]})
(${rsDone}/$ShardNum)." ;
exit 2
fi
done
echo "replicaSet initiated (${rsDone}/$ShardNum)"
export addShardF=$(mktemp)
echo "use admin;" >${addShardF}
for sh in ${!shAddSet[*]} ; do
echo "${shAddSet[$sh]}" >>${addShardF}
done
echo "add replica Sets to Shard"
mongo --port ${MongosPort} < ${addShardF} >/dev/null
#echo ${addShardF}
echo "add example data to test.ctest{Name,Age,Job,State}"
mongo --port ${MongosPort} >/dev/null 2>/dev/null << EOF
use test
switched to db test
db.ctest.drop();
use admin
sh.enableSharding('test')
db.ctest.ensureIndex({ Name : 1}, {unique:1});
sh.shardCollection("test.ctest", {Name:1})
use test
switched to db test
db.ctest.save({Name: "Frank", Age:56, Job: "Accountant", State: "NY"});
db.ctest.save({Name: "Bill" , Age:23, State: "CA"});
db.ctest.save({Name: "Janet", Age:34, Job: "Dancer" });
db.ctest.save({Name: "Andy", Age:44 });
db.ctest.save({Name: "Zach", Age:23, Job: "Fireman", State: "CA"});
i=1;
while(i<=100) {
j = 1;
while (j<=100) {
db.ctest.save({Name:"Person("+i+","+j+")", Age:i+j});
j = j + 1;
};
i = i + 1;
};
EOF
echo -e "\n#######\nShard prepared. use: 'mongo --port ${MongosPort}'. (your admin)\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment