• 根据主机IP列表自动部署指定规模的redis cluster


    新增功能:

    1、特殊环境下部署,添加针对少于3台(0台,1台,2台)机器的时候的提示,规划和部署。

    2、添加集群初始端口和集群规模的默认值。

    #!/bin/bash
     
     
    #集群初始端口,递增1
    port=${2:-'6379'}
     
    #集群的master个数
    cluster_size=${3:-'3'}
    
    iplist=$1
     
    total_parameters=$#
    function check_parameters()
    {
        if [[ $total_parameters -lt 1 ]];then
            echo "参数个数不匹配,请检查"
            echo "------------usage-----------------"
            echo "iplist=$1		#机器IP文件,必选参数"
            echo "port=$2			#redis集群初始端口,递增1,如未提供,默认初始端口为6379"
            echo "cluster_size=$3		#redis集群的master个数,如未提供,默认值是3"
            exit
        fi
    } 
     
    function make_cluster_map()
    {
    [ -f master_slave_map ] && >master_slave_map
    
    
    #当tag大于集群cluster_size时用于退出循环
    tag=0
    tag2=0
    
    #控制读取的机器IP文件的第几行
    i=1
    
    #获取机器IP文件的最后一行内容,如果循环未结束,区分在等于master或slave时候,重置i的值
    last_row=$(cat iplist | sed -n "$"p)
    
    rows=$(cat iplist | wc -l)
     
    while true
    do
        let tag=tag+1
        if [[ $tag -le $cluster_size ]];then
    		if [[ $rows -eq 0 ]];then
    			echo "至少需要一台机器,请检查iplist文件"
    			exit
    		elif [[ $rows -eq 1 ]];then
    			master_instance=$last_row
    			echo -n "$master_instance:$port#" >> master_slave_map
    			slave_instance=$last_row
    			let port=port+1
    			echo "$slave_instance:$port" >> master_slave_map
    			let port=port+1
    		elif [[ $rows -eq 2 ]];then
    			line1=$(cat iplist | sed -n "1"p)
    			line2=$(cat iplist | sed -n "2"p)
    			if [[ $tag2 -eq 0 ]];then
    				master_instance=$line1
    				slave_instance=$line2
    				echo "$master_instance:$port#$slave_instance:$port" >> master_slave_map
    				let port=port+1
    				let tag2=1
    				continue
    			fi
    			if [[ $tag2 -eq 1 ]];then
    				master_instance=$line2
    				slave_instance=$line1
    				echo "$master_instance:$port#$slave_instance:$port" >> master_slave_map
    				let port=port+1
    				let tag2=0
    				continue
    			fi
    		
    		elif [[ $rows -gt 2 ]];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
    		fi
    	else
    		#生成指定规模的集群实例后退出循环
    		break
    	fi
    done
     
    
    }
     
     
     
    function check_exists_port()
    {
    [ -f check_exists_port ] && >check_exists_port
     
    cat master_slave_map | tr '#' '
    ' > 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 '#' '
    ' | 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 '
    ' ' '  > 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
    "
    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()
    {
    # 0、 检查传参
    check_parameters
    
    # 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 $@
    

      

  • 相关阅读:
    vsftp配置文件
    oracle 7.4安装nvidia驱动
    python3.5-tensorflow-keras 安装
    linux 下u盘只读
    ubuntu1604-Python35-cuda9-cudnn7-gpu-dockerfile
    prometheus及gpu,k8s
    简单配置prometheus
    镜像源操作-ananconda-docker
    源码编译git-go
    ubuntu 微信安装-废弃
  • 原文地址:https://www.cnblogs.com/imdba/p/14071010.html
Copyright © 2020-2023  润新知