#!/bin/bash # # Cluster init ! # #function ProgressBar { # # Process data # let _progress=(${1}*100/${2}*100)/100 # let _done=(${_progress}*4)/10 # let _left=40-$_done # # Build progressbar string lengths # _fill=$(printf "%${_done}s") # _empty=$(printf "%${_left}s") # # # 1.2 Build progressbar strings and print the ProgressBar line # # 1.2.1 Output example: # # 1.2.1.1 Progress : [########################################] 100% # printf "\rProgress : [${_fill// /#}${_empty// /-}] ${_progress}%%" #} function redisRun() { cmd="redis-cli" host=$1 shift port=$1 shift #pass=$1 #shift #opt="-h ${host} -p ${port} -a ${pass}" opt="-h ${host} -p ${port}" act=${@} ${cmd} ${opt} ${act} return ${?} } # # Get Node ID with IP Adress and Port Number # Params : # - $1 => Leader IP # - $2 => Leader Port # - $3 => Cluster Password # - $4 => Node IP Adress # - $5 => Node Port # function getNodeID() { if [[ ${1} == ${3} ]] then searchCmd="awk '/myself,master/ { print \$1 }'" else searchCmd="awk '/${3}:${4}@/ { print \$1 }'" fi redisRun $1 $2 cluster nodes | eval ${searchCmd} return ${?} } function redisClusterForgetAll() { local res=0 for node in $(redisRun ${1} ${2} ${3} cluster nodes | awk '!/myself,master/ {print $1}') do redisRun ${1} ${2} ${3} "cluster forget ${node}" res=$((res+${?})) done return ${res} } # # Assing redis slots to master Node # Params : # - $1 => Node IP # - $2 => Node Port # - $3 => Cluster Password # - $4 => First slot # - $5 => Last slot # function redisSlotAssign() { res=0 for slot in $(seq ${3} ${4}) do OUT=$(redisRun ${1} ${2} "cluster ADDSLOTS $slot") res=$((res+${?})) if [[ ${OUT} =~ ERR ]] then OUT=$(redisRun ${1} ${2} "cluster ADDSLOTS $slot") fi done return ${res} } function redisAddReplica() { redisRun ${1} ${2} "cluster replicate ${3}" return ${?} } function redisClusterIsOK() { out=$(redis-cli -h ${1} -p ${2} cluster info | grep "cluster_state:ok") return $? } CONF="/etc/redis/cluster.conf" [[ ! -e ${CONF} ]] && exit 0 declare -A IPADDRS declare -A PORTS declare -A ROLES declare -A MASTERS declare -A NIDS index=0 while read line do line=${line//::/:none:} li=(${line//:/ }) name=${li[0]} ip=${li[1]} port=${li[2]} role=${li[3]} master=${li[4]} NAMES+=(${name}) IPADDRS+=([${name}]=${ip}) PORTS+=([${name}]=${port}) ROLES+=([${name}]=${role}) MASTERS+=([${name}]=${master}) done < ${CONF} # If the cluster is "ok" don't do anything st=$(redisClusterIsOK ${IPADDRS["Leader"]} ${PORTS["Leader"]}) #[[ ${?} -eq 0 ]] && exit 0 if [[ ${1} == "forget" ]] then redisClusterForgetAll ${IPADDRS["Leader"]} ${PORTS["Leader"]} exit ${?} fi echo " * Organise Cluster Meeting." for node in ${NAMES[@]} do act="cluster meet ${IPADDRS[${node}]} ${PORTS[${node}]}" echo " - ${node} - ${IPADDRS[${node}]}:${PORTS[${node}]} meeting with :" for oth in ${NAMES[@]} do [[ ${oth} == ${node} ]] && continue echo -en " -> ${oth} - ${IPADDRS[${oth}]} ${PORTS[${oth}]} " redisRun ${IPADDRS[${oth}]} ${PORTS[${oth}]} "${act}" done done echo " * Waiting for all members ." for node in ${NAMES[@]} do try=3 scmd="awk '/${IPADDRS[$node]}:${PORTS[${node}]}/ {print \$8}'" while [[ $(redisRun ${IPADDRS['Leader']} ${PORTS['Leader']} "cluster nodes" | eval ${scmd}) != "connected" ]] do sleep 1 try=$((try-1)) [[ ${try} -eq 0 ]] break done done nbMaster=$(grep -c ":master" ${CONF}) totalslots=16384 perNodeSlots=$((totalslots/nbMaster)) startSlot=0 echo " * Assign Slots to the nodes." for node in ${NAMES[@]} do if [[ ${ROLES[$node]} == "master" ]] then if [[ ${startSlot} -eq 0 ]] then lastSlot=$(((perNodeSlots+startSlot)-1)) else lastSlot=$((perNodeSlots+startSlot)) fi [[ ${lastSlot} -ge ${totalslots} ]] && lastSlot=$((totalslots-1)) echo " - Slots ${startSlot} to ${lastSlot} => ${node} - ${IPADDRS[${node}]} ${PORTS[${node}]}" redisSlotAssign ${IPADDRS[${node}]} ${PORTS[${node}]} ${startSlot} ${lastSlot} startSlot=$((lastSlot+1)) fi done echo " * Configuring replication." NIDS+=() for node in ${NAMES[@]} do NIDS+=([${node}]=$(getNodeID ${IPADDRS["Leader"]} ${PORTS["Leader"]} ${IPADDRS[${node}]} ${PORTS[${node}]})) done for node in ${NAMES[@]} do [[ ${ROLES[$node]} == "master" ]] && continue echo -ne " - Replicate ${MASTERS[${node}]} to ${node}\t\t" redisAddReplica ${IPADDRS[${node}]} ${PORTS[${node}]} ${NIDS[${MASTERS[${node}]}]} done sleep 2 echo echo "Cluster status :" echo redisRun ${IPADDRS["Leader"]} ${PORTS["Leader"]} cluster info echo exit 0