eole-redis/postservice/90-redis-init
Philippe Caseiro 2cb3b1eab0 Adding support for a second instance !
Redis cluster needs 6 hosts for work ... it's a lot.
To trick him each node can be Master and slave for another node.

;)
2020-06-17 12:16:27 +02:00

237 lines
5.1 KiB
Bash
Executable File

#!/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
result=$(redisRun $1 $2 cluster nodes | eval ${searchCmd})
rcode=${?}
if [[ -z ${result} ]]
then
searchCmd="awk '/${3}:${4}@/ { print \$1 }'"
result=$(redisRun $1 $2 cluster nodes | eval ${searchCmd})
rcode=${?}
fi
echo ${result}
return ${rcode}
}
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
declare LeaderIP
declare LeaderPort
index=0
while read line
do
[[ ${line} =~ ^# ]] && continue
line=${line//::/:none:}
li=(${line//:/ })
name=${li[0]}
ip=${li[1]}
port=${li[2]}
role=${li[3]}
master=${li[4]}
ntype=${li[5]}
if [[ ${ntype} == "Leader" ]]
then
LeaderIP=${ip}
LeaderPort=${port}
fi
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 ${LeaderIP} ${LeaderPort})
#[[ ${?} -eq 0 ]] && exit 0
if [[ ${1} == "forget" ]]
then
redisClusterForgetAll ${LeaderIP} ${LeaderPort}
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 ${LeaderIP} ${LeaderPort} "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 ${LeaderIP} ${LeaderPort} ${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 5
echo
echo "Cluster status :"
echo
redisRun ${LeaderIP} ${LeaderPort} cluster info
echo
exit 0