一、目录结构与使用说明

1.1 目录中的文件

  • install_redis_single.sh:Redis 单实例安装脚本。
  • install_redis_multi.sh:Redis 多实例安装脚本。
  • ReadMe.md:说明软件包和脚本需要放在同一目录下。

1.2 这组脚本的共通思路

  • 自动安装编译依赖。
  • 下载或复用 Redis 源码包。
  • 编译安装到统一目录。
  • 生成配置文件并注册 systemd 服务。
  • 调整 somaxconnvm.overcommit_memory 和透明大页设置。

二、单实例脚本整理

2.1 单实例部署的关键流程

REDIS_VERSION=redis-7.4.2
PASSWORD=<your-password>
INSTALL_DIR=/apps/redis

make -j "$CPUS" USE_SYSTEMD=yes PREFIX="${INSTALL_DIR}" install
cp redis.conf "${INSTALL_DIR}/etc/"
sed -i.bak \
  -e "/^bind/c bind 0.0.0.0" \
  -e "\$a requirepass ${PASSWORD}" \
  -e "/^dir .*/c dir ${INSTALL_DIR}/data/" \
  "${INSTALL_DIR}/etc/redis.conf"

2.2 发布时建议顺手修正的小问题

原单实例脚本里使用了 make -j $CUPS,但前面定义的变量名是 CPUS。正式发布前建议统一成 make -j "$CPUS",否则并发编译参数可能为空。

三、多实例脚本整理

3.1 多实例端口规划

for PORT in "${REDIS_PORTS[@]}"; do
    INSTANCE_DIR="${INSTALL_DIR}/${PORT}"
    mkdir -p "${INSTANCE_DIR}/"{etc,log,data,run}
    cp redis.conf "${INSTANCE_DIR}/etc/redis_${PORT}.conf"
    sed -i.bak \
      -e "s/^port .*/port ${PORT}/" \
      -e "s#^dir .*#dir ${INSTANCE_DIR}/data#" \
      -e "s#^logfile .*#logfile ${INSTANCE_DIR}/log/redis_${PORT}.log#" \
      "${INSTANCE_DIR}/etc/redis_${PORT}.conf"
done

3.2 systemd 模板化服务

cat > "/etc/systemd/system/redis@${PORT}.service" <<EOF
[Unit]
Description=Redis Server on port ${PORT}
After=network.target

[Service]
ExecStart=/apps/redis/bin/redis-server ${INSTANCE_DIR}/etc/redis_${PORT}.conf --supervised systemd
User=redis
Group=redis
EOF

四、发布前建议

4.1 建议补充的验证命令

  • redis-cli -a <your-password> ping
  • systemctl status redis
  • systemctl status redis@6379

五、完整脚本

以下为本文对应的完整脚本,便于直接复制复用。

5.1 install_redis_single.sh

#!/bin/bash
#
#********************************************************************
#Author:          zhangqing
#QQ:              1904763431
#Date:            2020-07-22
#FileName:       install_redis.sh
#URL:             http://www.zhang-qing.com
#Description:     Redis 单实例安装脚本(支持 CentOS、Rocky、Ubuntu)
#Copyright (C):   2020 All rights reserved
#********************************************************************

#本脚本支持在线和离线安装

REDIS_VERSION=redis-7.4.2
#REDIS_VERSION=redis-7.2.5
#REDIS_VERSION=redis-7.2.4
#REDIS_VERSION=redis-7.2.3
#REDIS_VERSION=redis-7.2.1
#REDIS_VERSION=redis-7.0.11
#REDIS_VERSION=redis-7.0.7
#REDIS_VERSION=redis-7.0.3
#REDIS_VERSION=redis-6.2.6
#REDIS_VERSION=redis-4.0.14

PASSWORD=123456

INSTALL_DIR=/apps/redis

CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`

. /etc/os-release

color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "    
    elif [ $2 = "failure" -o $2 = "1"  ] ;then 
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo 
}

prepare(){
    if [ $ID = "centos" -o $ID = "rocky" ];then
        yum  -y install gcc make jemalloc-devel systemd-devel
    else
        apt update 
        apt -y install  gcc make libjemalloc-dev libsystemd-dev
    fi
    if [ $? -eq 0 ];then
        color "安装软件包成功"  0
    else
        color "安装软件包失败,请检查网络配置" 1
        exit
    fi
}

install() {   
    if [ ! -f ${REDIS_VERSION}.tar.gz ];then
        wget http://download.redis.io/releases/${REDIS_VERSION}.tar.gz || { color "Redis 源码下载失败" 1 ; exit; }
    fi
    tar xf ${REDIS_VERSION}.tar.gz -C /usr/local/src
    cd /usr/local/src/${REDIS_VERSION}
    make -j $CUPS USE_SYSTEMD=yes PREFIX=${INSTALL_DIR} install && color "Redis 编译安装完成" 0 || { color "Redis 编译安装失败" 1 ;exit ; }

    ln -s ${INSTALL_DIR}/bin/redis-*  /usr/local/bin/

    mkdir -p ${INSTALL_DIR}/{etc,log,data,run}

    cp redis.conf  ${INSTALL_DIR}/etc/

    sed -i.bak \
    -e "/^bind/c bind 0.0.0.0" \
    -e "\$a requirepass ${PASSWORD}" \
    -e "/^dir .*/c dir ${INSTALL_DIR}/data/" \
    -e "/logfile .*/c logfile ${INSTALL_DIR}/log/redis_6379.log" \
    -e "/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis_6379.pid" \
    ${INSTALL_DIR}/etc/redis.conf

    if id redis &> /dev/null ;then 
         color "Redis 用户已存在" 1 
    else
         useradd -r -s /sbin/nologin redis
         color "Redis 用户创建成功" 0
    fi

    chown -R redis.redis ${INSTALL_DIR}

    cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
    sysctl -p 
    if [ $ID = "centos" -o $ID = "rocky" ];then
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
        chmod +x /etc/rc.d/rc.local
        /etc/rc.d/rc.local 
    else 
        echo -e '#!/bin/bash\necho never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
        chmod +x /etc/rc.local
        /etc/rc.local
    fi

cat > /lib/systemd/system/redis.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=1000000

[Install]
WantedBy=multi-user.target

EOF
     systemctl daemon-reload 
     systemctl enable --now  redis &> /dev/null 
     if [ $? -eq 0 ];then
         color "Redis 服务启动成功,Redis信息如下:"  0 
     else
        color "Redis 启动失败" 1 
        exit
     fi
     sleep 2
     redis-cli -a $PASSWORD INFO Server 2> /dev/null
}

prepare 

install

5.2 install_redis_multi.sh

#!/bin/bash
#
#********************************************************************
#Author:          zhangqing
#QQ:              1904763431
#Date:            2020-07-22
#FileName:       install_redis.sh
#Description:     Redis 多实例安装脚本(支持 CentOS、Rocky、Ubuntu)
#Copyright (C):   2020 All rights reserved
#********************************************************************

# Redis 版本
REDIS_VERSION=redis-7.4.2
#REDIS_VERSION=redis-7.2.5
#REDIS_VERSION=redis-7.2.4
#REDIS_VERSION=redis-7.2.3
#REDIS_VERSION=redis-7.2.1
#REDIS_VERSION=redis-7.0.11
#REDIS_VERSION=redis-7.0.7
#REDIS_VERSION=redis-7.0.3
#REDIS_VERSION=redis-6.2.6
#REDIS_VERSION=redis-4.0.14

# Redis 监听端口(多个实例使用空格分隔)
REDIS_PORTS=("6379" "6380" "6381")

# Redis 安装目录
INSTALL_DIR=/apps/redis

# Redis 认证密码
PASSWORD=123456

# CPU 核心数
CPUS=$(nproc)

# 获取系统信息
. /etc/os-release

color() {
    local text=$1
    local status=$2
    local GREEN="\033[1;32m"
    local RED="\033[1;31m"
    local YELLOW="\033[1;33m"
    local RESET="\033[0m"

    echo -ne "$text"
    echo -ne " ["
    case $status in
        0) echo -e "${GREEN}  OK  ${RESET}" ;;
        1) echo -e "${RED}FAILED${RESET}" ;;
        *) echo -e "${YELLOW}WARNING${RESET}" ;;
    esac
    echo "]"
}

prepare() {
    echo "正在安装必要的软件包..."
    if [[ $ID == "centos" || $ID == "rocky" ]]; then
        yum -y install gcc make jemalloc-devel systemd-devel
    else
        apt update && apt -y install gcc make libjemalloc-dev libsystemd-dev
    fi

    if [[ $? -eq 0 ]]; then
        color "依赖包安装成功" 0
    else
        color "依赖包安装失败,请检查网络" 1
        exit 1
    fi
}

install() {
    # 下载 Redis 源码
    if [[ ! -f ${REDIS_VERSION}.tar.gz ]]; then
        wget http://download.redis.io/releases/${REDIS_VERSION}.tar.gz || { color "Redis 源码下载失败" 1; exit 1; }
    fi

    # 编译安装 Redis
    tar xf ${REDIS_VERSION}.tar.gz -C /usr/local/src
    cd /usr/local/src/${REDIS_VERSION}
    make -j "$CPUS" USE_SYSTEMD=yes PREFIX="${INSTALL_DIR}" install && color "Redis 编译安装完成" 0 || { color "Redis 编译安装失败" 1; exit 1; }

    # 软链接
    ln -sf "${INSTALL_DIR}/bin/redis-"* /usr/local/bin/

    # 创建 Redis 用户
    if ! id redis &>/dev/null; then
        useradd -r -s /sbin/nologin redis
        color "Redis 用户创建成功" 0
    else
        color "Redis 用户已存在" 1
    fi

    # 内核参数优化
    cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
    sysctl -p

    # 禁用透明大页
    if [[ $ID == "centos" || $ID == "rocky" ]]; then
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
        chmod +x /etc/rc.d/rc.local
        /etc/rc.d/rc.local
    else
        echo -e '#!/bin/bash\necho never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
        chmod +x /etc/rc.local
        /etc/rc.local
    fi

    # 配置多个 Redis 实例
    for PORT in "${REDIS_PORTS[@]}"; do
        INSTANCE_DIR="${INSTALL_DIR}/${PORT}"
        mkdir -p "${INSTANCE_DIR}/"{etc,log,data,run}

        # 复制 Redis 配置文件
        cp redis.conf "${INSTANCE_DIR}/etc/redis_${PORT}.conf"

        # 修改配置文件
        sed -i.bak \
            -e "s/^port .*/port ${PORT}/" \
            -e "s/^bind.*/bind 0.0.0.0/" \
            -e "s#^dir .*#dir ${INSTANCE_DIR}/data#" \
            -e "s#^logfile .*#logfile ${INSTANCE_DIR}/log/redis_${PORT}.log#" \
            -e "s#^pidfile .*#pidfile ${INSTANCE_DIR}/run/redis_${PORT}.pid#" \
            -e "\$a requirepass ${PASSWORD}" \
            "${INSTANCE_DIR}/etc/redis_${PORT}.conf"

        # 设置权限
        chown -R redis:redis "${INSTANCE_DIR}"

        # 创建 systemd 服务文件
        cat > "/etc/systemd/system/redis@${PORT}.service" <<EOF
[Unit]
Description=Redis Server on port ${PORT}
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTANCE_DIR}/etc/redis_${PORT}.conf --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis_${PORT}
RuntimeDirectoryMode=0755
LimitNOFILE=1000000

[Install]
WantedBy=multi-user.target
EOF

        # 启动 Redis 服务
        systemctl daemon-reload
        systemctl enable --now redis@"${PORT}" && color "Redis ${PORT} 实例启动成功" 0 || color "Redis ${PORT} 启动失败" 1
    done

    # 显示所有实例状态
    echo "所有 Redis 实例状态:"
    for PORT in "${REDIS_PORTS[@]}"; do
        systemctl status redis@"${PORT}" --no-pager
    done
}

prepare
install