#!/bin/bash # Redis哨兵集群部署与卸载脚本 # 颜色配置 GREEN="\033[32m" YELLOW="\033[33m" BLUE="\033[34m" RED="\033[31m" RESET="\033[0m" # 提示函数 info() { echo -e "[ ${BLUE}INFO ${RESET}] $1"; } success() { echo -e "[ ${GREEN}SUCCESS ${RESET}] $1"; } warning() { echo -e "[ ${YELLOW}WARNING ${RESET}] $1"; } error() { echo -e "[ ${RED}ERROR ${RESET}] $1"; exit 1; } # 基础配置 REDIS_PORT=6379 SENTINEL_PORT=26379 SENTINEL_NAME="mymaster" LOG_DIR="/var/log/redis" CONFIG_DIR="/etc/redis" SSH_OPTS="-T -o StrictHostKeyChecking=no -o LogLevel=ERROR" # 全局变量 ACTION="" NODES=() NODE_COUNT=0 MASTER="" SLAVES=() QUORUM=1 PASSWORD="" # 参数解析(支持--install/--uninstall、--ip、--passwd参数) parse_args() { # 初始化参数变量 local ip_provided=0 local passwd_provided=0 # 遍历解析参数 while [[ $# -gt 0 ]]; do case "$1" in --install|--uninstall) ACTION="$1" shift ;; --ip=*) IP_LIST="${1#*=}" ip_provided=1 shift ;; --passwd=*) PASSWORD="${1#*=}" passwd_provided=1 shift ;; *) error "无效参数: $1 (使用帮助:--install/--uninstall --ip=IP1,IP2,IP3... --passwd=redis密码)" ;; esac done # 验证必要参数 if [[ -z "$ACTION" ]]; then error "必须指定参数:--install/--uninstall --ip=IP1,IP2,IP3... --passwd=redis密码" fi if [[ $ip_provided -eq 0 ]]; then error "必须指定参数:--install/--uninstall --ip=IP1,IP2,IP3... --passwd=redis密码" fi if [[ $passwd_provided -eq 0 ]]; then error "必须指定参数:--install/--uninstall --ip=IP1,IP2,IP3... --passwd=redis密码" fi # 解析节点列表 IFS=',' read -ra NODES <<< "$IP_LIST" NODE_COUNT=${#NODES[@]} if [[ $NODE_COUNT -lt 1 ]]; then error "IP列表不能为空,至少需要1个节点" fi # 配置主从节点和投票阈值 MASTER="${NODES[0]}" SLAVES=("${NODES[@]:1}") QUORUM=$((NODE_COUNT / 2 + 1)) # 自动计算投票阈值 } # 安装流程核心函数 install() { echo -e "==========================================" echo -e "=== ${GREEN}Redis哨兵集群安装部署${RESET} ===" echo -e "==========================================" info "部署节点总数:$NODE_COUNT 个(${NODES[*]})" info "主节点:$MASTER | 从节点:${SLAVES[*]}(共${#SLAVES[@]}个)" info "哨兵投票阈值(QUORUM):$QUORUM(自动计算:$NODE_COUNT/2 +1)" info "Redis密码:******(已通过命令行传入)" info "预估总耗时:9-14 分钟(视节点数和网络)" echo -e "==========================================\n" # 步骤1:初始化环境 info "步骤1/5:初始化所有节点环境 [${YELLOW}预估:5-9 分钟${RESET}]" info "正在安装依赖、配置日志目录和防火墙..." for node in "${NODES[@]}"; do ssh $SSH_OPTS $node " apt-get update -y >/dev/null 2>&1; apt-get install -y redis-server redis-sentinel net-tools >/dev/null 2>&1; mkdir -p $CONFIG_DIR $LOG_DIR; chown -R redis:redis $CONFIG_DIR $LOG_DIR; ufw disable >/dev/null 2>&1; iptables -F INPUT >/dev/null 2>&1; " >/dev/null 2>&1 || error "节点 $node 环境初始化失败" done success "步骤1完成:所有节点环境初始化完毕\n" # 步骤2:配置主节点 info "步骤2/5:配置主节点 $MASTER [${YELLOW}预估:30秒${RESET}]" ssh $SSH_OPTS $MASTER " cat > $CONFIG_DIR/redis.conf < /etc/systemd/system/redis.service </dev/null 2>&1 || error "主节点 $MASTER 配置失败" success "步骤2完成:主节点配置完毕\n" # 步骤3:配置从节点 info "步骤3/5:配置从节点 [${YELLOW}预估:${#SLAVES[@]}*30秒${RESET}]" info "从节点列表:${SLAVES[*]}" for slave in "${SLAVES[@]}"; do info "正在配置从节点:$slave" ssh $SSH_OPTS $slave " cat > $CONFIG_DIR/redis.conf < /etc/systemd/system/redis.service </dev/null 2>&1 || error "从节点 $slave 配置失败" done success "步骤3完成:所有从节点配置完毕\n" # 步骤4:配置哨兵集群 info "步骤4/5:配置哨兵集群 [${YELLOW}预估:$NODE_COUNT*30秒${RESET}]" info "哨兵投票阈值:$QUORUM(需$QUORUM个哨兵确认主节点下线才触发转移)" for node in "${NODES[@]}"; do info "正在配置哨兵节点:$node" ssh $SSH_OPTS $node " cat > $CONFIG_DIR/sentinel.conf < /etc/systemd/system/redis-sentinel.service </dev/null 2>&1 || error "哨兵节点 $node 配置失败" done success "步骤4完成:哨兵集群配置完毕\n" # 步骤5:验证集群 info "步骤5/5:验证集群状态 [${YELLOW}预估:1分钟${RESET}]" info "验证主节点 $MASTER..." master_info=$(ssh $SSH_OPTS $MASTER "redis-cli -p $REDIS_PORT -a $PASSWORD info replication | grep -E 'role:|connected_slaves'" 2>/dev/null) echo " $master_info" for slave in "${SLAVES[@]}"; do info "验证从节点 $slave..." slave_info=$(ssh $SSH_OPTS $slave "redis-cli -p $REDIS_PORT -a $PASSWORD info replication | grep -E 'role:|master_host|master_link_status'" 2>/dev/null) echo " $slave_info" done info "验证哨兵集群..." sentinel_info=$(ssh $SSH_OPTS $MASTER "redis-cli -p $SENTINEL_PORT info sentinel | grep 'master0:'" 2>/dev/null) echo " $sentinel_info" success "步骤5完成:集群验证完毕\n" # 部署总结 echo -e "==========================================" echo -e "=== ${GREEN}部署成功!${RESET} ===" echo -e "☆ 集群架构:$NODE_COUNT节点(1主${#SLAVES[@]}从$NODE_COUNT哨兵)" echo -e "☆ 核心配置:Redis端口$REDIS_PORT | 哨兵端口$SENTINEL_PORT | 投票阈值$QUORUM" echo -e "☆ 功能状态:主从同步正常 | 哨兵监控正常 | 故障转移就绪" echo -e "==========================================" } # 卸载流程核心函数 uninstall() { echo -e "==========================================" echo -e "=== ${RED}Redis哨兵集群彻底卸载${RESET} ===" echo -e "==========================================" info "卸载节点列表:${NODES[*]}(共$NODE_COUNT个节点)" info "Redis密码:******(已通过命令行传入)" info "预估耗时:3-6 分钟(清理所有资源)" echo -e "==========================================\n" # 逐节点卸载 for i in "${!NODES[@]}"; do node="${NODES[$i]}" idx=$((i + 1)) info "正在卸载节点($idx/$NODE_COUNT):$node" ssh $SSH_OPTS $node " # 停止服务(使用传入的密码) systemctl stop redis-sentinel >/dev/null 2>&1; redis-cli -p $REDIS_PORT -a '$PASSWORD' shutdown >/dev/null 2>&1; # 禁用服务 systemctl disable redis redis-sentinel >/dev/null 2>&1; # 清理文件 rm -rf $CONFIG_DIR $LOG_DIR /etc/systemd/system/redis* >/dev/null 2>&1; # 卸载依赖 apt-get remove -y redis-server redis-sentinel >/dev/null 2>&1; apt-get autoremove -y >/dev/null 2>&1; " >/dev/null 2>&1 || error "节点 $node 卸载失败" success "节点 $node 卸载完成" done # 卸载总结 echo -e "\n==========================================" echo -e "=== ${GREEN}卸载成功!${RESET} ===" echo -e "✓ 已彻底清理所有Redis相关资源:" echo -e " - 服务:redis-server、redis-sentinel(停止+禁用)" echo -e " - 文件:配置目录、日志目录、systemd服务文件" echo -e " - 依赖:redis相关安装包及依赖组件" echo -e "==========================================" } # 执行入口 parse_args "$@" if [ "$ACTION" = "--install" ]; then install elif [ "$ACTION" = "--uninstall" ]; then uninstall fi