zoukankan      html  css  js  c++  java
  • 根据主机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 $@
    

      

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/imdba/p/14071010.html
Copyright © 2011-2022 走看看