根據主機IP列表自動部署指定規模的redis cluster
阿新 • • 發佈:2020-12-02
指令碼雛形思路:
#!/bin/bash #叢集初始埠,遞增1 port=$1 #叢集的master個數 cluster_size=$2 function make_cluster_map() { [ -f master_slave_map ] && >master_slave_map #當tag大於叢集cluster_size時用於退出迴圈 tag=0 #控制讀取的機器IP檔案的第幾行 i=1 #獲取機器IP檔案的最後一行內容,如果迴圈未結束,區分在等於master或slave時候,重置i的值 last_row=$(cat iplist | sed -n "$"p) while true do let tag=tag+1 if [[ $tag -le $cluster_size ]];then master_instance=$(cat iplist | sed -n "$i"p) #如果master對應的是機器IP檔案的最後1行 if [[ "$master_instance" == "$last_row" ]];then master_instance=$last_row #slave對應的就應該是機器IP檔案的第1行 slave_instance=$(cat iplist | sed -n "1"p) echo "$master_instance:$port#$slave_instance:$port" >> master_slave_map #如果迴圈沒有退出,那麼下一次的master應該是對應機器IP檔案的第2行,即置i=2 let i=2 else let i=i+1 slave_instance=$(cat iplist | sed -n "$i"p) #如果slave對應的機器IP檔案的最後1行 if [[ "$slave_instance" == "$last_row" ]];then echo "$master_instance:$port#$slave_instance:$port" >> master_slave_map #如果迴圈沒有退出,那麼下一次的master應該是對應機器IP檔案的第1行,即置i=1 let i=1 else echo "$master_instance:$port#$slave_instance:$port" >> master_slave_map let i=i+1 fi fi #迴圈未結束,下一批次的埠加1 let port=port+1 else #生成指定規模的叢集例項後退出迴圈 break fi done } function check_exists_port() { [ -f check_exists_port ] && >check_exists_port cat master_slave_map | tr '#' '\n' > all_redis_instance for line in $(cat all_redis_instance) do { check_ip=$(echo $line | awk -F':' '{print $1}') check_port=$(echo $line | awk -F':' '{print $2}') nums=$(ssh $check_ip "ss -utp state listening sport == :${check_port} |wc -l") if [[ $nums -ge 2 ]];then echo "$check_ip機器上已存在埠$check_port" >> check_exists_port fi }& done wait if [[ -s check_exists_port ]];then echo "存在埠衝突,退出部署,詳情請檢視check_exists_port檔案內容。" exit fi } function create_user_copy_redis_soft() { [ -f "copy_hosts" ] && >copy_hosts for i in `cat iplist` do echo $i | tr '.' '_' | awk '{print "["$1"]"}' >> copy_hosts echo $i >> copy_hosts echo >> copy_hosts done for ip in `cat iplist` do ansible -i copy_hosts $ip -m user -a "name=redis home=/home/redis shell=/sbin/nologin" --become --become-method=sudo --become-user=root ansible -i copy_hosts $ip -m copy -a "src=/usr/local/redis-5.0.3.tar dest=/usr/local/ owner=redis group=redis mode=0755" ansible -i copy_hosts $ip -m shell -a "cd /usr/local/; tar xf redis-5.0.3.tar" ansible -i copy_hosts $ip -m shell -a "chown -R redis:redis /usr/local/redis-5.0.3" done } function make_ansible_inventory() { cat master_slave_map |tr '#' '\n' | awk '{print "ip_"$1}'| sort -t ':' -nk1 | tr ':' '_' | tr '.' '_' > all_instance [ -f "ip.list" ] && >ip.list for i in `cat all_instance` do echo "[$i]" >> ip.list myip=$(grep $i all_instance | awk -F'_' '{print $2"."$3"."$4"."$5}') myport=$(grep $i all_instance | awk -F['_'] '{print $NF}') echo "$myip redis_port=$myport" >> ip.list echo >> ip.list done } function make_dirs_copy_cnf_change_cnf() { for i in `cat all_instance` do myip=$(grep $i all_instance | awk -F'_' '{print $2"."$3"."$4"."$5}') myport=$(grep $i all_instance | awk -F['_'] '{print $NF}') ansible -i ip.list ${myip} -m shell -a "mkdir -pv /etc/redis/;mkdir -pv /dbdata/redis/redis5.0.3/$myport/{data,conf,log};chown -R redis:redis /dbdata/redis/redis5.0.3/$myport" ansible -i ip.list ${myip} -m copy -a "src=/usr/local/redis.conf dest=/etc/redis owner=redis group=redis mode=0755" ansible -i ip.list ${myip} -m shell -a "cd /etc/redis;mv redis.conf redis_$myport.conf;sed -i 's/27008/'$myport'/g' redis_$myport.conf" done } function start_all_redis_instance() { for i in `cat all_instance` do myip=$(grep $i all_instance | awk -F'_' '{print $2"."$3"."$4"."$5}') myport=$(grep $i all_instance | awk -F['_'] '{print $NF}') ansible -i ip.list ${myip} -m shell -a "/usr/local/redis-5.0.3/src/redis-server /etc/redis/redis_$myport.conf" done } function make_redis_cluster_only_master() { cat master_slave_map | awk -F'#' '{print $1}' | tr '\n' ' ' > create_cluster_strings command="/usr/local/redis-5.0.3/src/redis-cli --cluster create `cat create_cluster_strings`" /usr/bin/expect <<-EOF spawn $command expect "yes" send "yes\r" expect eof EOF sleep 30 #這裡執行完畢後需要等待一會,否則可能會出現Nodes don't agree about configuration!的提示 } function add_slave_of_matched_master() { for i in `cat master_slave_map` do master_ip=$(echo $i | awk -F['#'] '{print $1}'| awk -F[':'] '{print $1}') master_port=$(echo $i | awk -F['#'] '{print $1}'| awk -F[':'] '{print $2}') slave_ip=$(echo $i | awk -F['#'] '{print $2}'| awk -F[':'] '{print $1}') slave_port=$(echo $i | awk -F['#'] '{print $2}'| awk -F[':'] '{print $2}') existing_ip_port=$master_ip:$master_port master_id=$(/usr/local/redis-5.0.3/src/redis-cli -h $master_ip -p $master_port cluster nodes | awk '/'$master_ip':'$master_port'/{print $1}') /usr/local/redis-5.0.3/src/redis-cli --cluster add-node $slave_ip:$slave_port $existing_ip_port --cluster-slave --cluster-master-id $master_id done } #if [[ $? -eq 0 ]];then # rm -rf all_instance # rm -rf copy_hosts # rm -rf create_cluster_strings # rm -rf hosts # rm -rf ip.list #fi function main() { # 1、根據主機列表生成待部署的叢集例項對應關係 make_cluster_map # 2、在目標機器上檢查對應的埠是否被佔用 check_exists_port # 3、在目標主機上建立redis使用者組和使用者,拷貝redis二進位制包 create_user_copy_redis_soft # 4、根據master_slave_map檔案生成ansible的inventory檔案 make_ansible_inventory # 5、呼叫ansible建立redis相關例項的目錄,配置檔案並修改配置檔案 make_dirs_copy_cnf_change_cnf # 6、呼叫ansible批量啟動所有redis例項 start_all_redis_instance # 7、建立redis cluster叢集,只新增master角色 make_redis_cluster_only_master # 8、根據master_slave_map檔案的對應關係,分別master新增對應的slave例項 add_slave_of_matched_master } main $@