#!/bin/bash set -e # ========================================== # 1. 参数检查 # ========================================== REDIS_PASSWORD=${1:-""} DATA_ROOT=${2:-""} if [ -z "$DATA_ROOT" ]; then echo "❌ 错误: 缺少参数!" echo "用法: $0 <密码> <数据根目录>" exit 1 fi if [ -z "$REDIS_PASSWORD" ]; then REDIS_PASSWORD=$(openssl rand -base64 12) echo "⚠️ 未提供密码,已生成随机密码: $REDIS_PASSWORD" fi LOG_DIR="$DATA_ROOT/log" DB_DIR="$DATA_ROOT/data" echo " 开始部署 Redis 8.0.3 (JuiceFS 优化版)" echo " 密码: $REDIS_PASSWORD" echo " 数据目录: $DATA_ROOT" echo " 日志目录: $LOG_DIR" # ========================================== # 2. 系统准备与安装 # ========================================== echo " 更新源并安装依赖..." apt-get update -qq # 移除 envsubst 依赖,只保留基础工具 apt-get install -y -qq software-properties-common curl gnupg > /dev/null # 导入 GPG 密钥 echo " 导入 Redis GPG 密钥..." curl -fsSL https://packages.redis.io/gpg | gpg --dearmor --yes -o /usr/share/keyrings/redis-archive-keyring.gpg # 添加源 if [ ! -f /etc/apt/sources.list.d/redis.list ]; then echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/redis.list > /dev/null fi apt-get update -qq REDIS_VERSION_FULL="6:8.0.3-1rl1~jammy1" echo " 安装 Redis $REDIS_VERSION_FULL ..." apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \ redis-server="$REDIS_VERSION_FULL" \ redis-tools="$REDIS_VERSION_FULL" # ========================================== # 3. 准备目录与权限 # ========================================== echo " 创建目录结构..." mkdir -p "$LOG_DIR" "$DB_DIR" id redis &>/dev/null || useradd -r -s /usr/sbin/nologin redis chown -R redis:redis "$DATA_ROOT" chmod 750 "$DATA_ROOT" chmod 750 "$LOG_DIR" chmod 750 "$DB_DIR" # ========================================== # 4. 生成 redis.conf (Cat 追加 + Sed 替换) # ========================================== echo "⚙️ 生成 redis.conf (使用 sed 替换变量)..." # 第一步:使用 cat 写入模板配置 (使用占位符 __VAR__) cat > /etc/redis/redis.conf << 'CONFEOF' # Redis Configuration Optimized for JuiceFS ################################## NETWORK ##################################### bind 0.0.0.0 ::0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 ################################# GENERAL ##################################### supervised systemd loglevel notice logfile __LOG_DIR__/redis-server.log databases 16 always-show-logo no set-proc-title yes proc-title-template "{title} {listen-addr} {server-mode}" ################################ SNAPSHOTTING (RDB) ############################ save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir __DB_DIR__ ################################# REPLICATION ################################# replica-serve-stale-data yes replica-read-only yes repl-diskless-sync yes repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no repl-backlog-size 1mb repl-backlog-ttl 3600 replica-priority 100 ################################## SECURITY ################################### requirepass __REDIS_PASSWORD__ ################################### CLIENTS #################################### maxclients 10000 ############################# LAZY FREEING #################################### lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no lazyfree-lazy-user-del no #################### KERNEL transparent hugepage CONTROL ###################### disable-thp yes ############################## APPEND ONLY MODE ############################### appendonly no appendfilename "appendonly.aof" appenddirname "appendonlydir" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes ################################## SLOW LOG ################################### slowlog-log-slower-than 10000 slowlog-max-len 128 ############################### ADVANCED CONFIG ############################### hash-max-listpack-entries 512 hash-max-listpack-value 64 list-max-listpack-size -2 list-compress-depth 0 set-max-intset-entries 512 set-max-listpack-entries 128 set-max-listpack-value 64 zset-max-listpack-entries 128 zset-max-listpack-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes ################################## MODULES ##################################### loadmodule /usr/lib/redis/modules/rejson.so loadmodule /usr/lib/redis/modules/redisbloom.so loadmodule /usr/lib/redis/modules/redistimeseries.so loadmodule /usr/lib/redis/modules/redisearch.so CONFEOF # 第二步:使用 sed 原地替换占位符为真实变量 # 注意:如果路径包含 /,sed 的替换分隔符需要用其他字符(如 |)避免冲突 sed -i "s|__LOG_DIR__|$LOG_DIR|g" /etc/redis/redis.conf sed -i "s|__DB_DIR__|$DB_DIR|g" /etc/redis/redis.conf sed -i "s|__REDIS_PASSWORD__|$REDIS_PASSWORD|g" /etc/redis/redis.conf # 修复权限 chown redis:redis /etc/redis/redis.conf chmod 640 /etc/redis/redis.conf echo "✅ redis.conf 生成并替换完成" # ========================================== # 5. 修改 Systemd Service 文件 # ========================================== echo " 适配 systemd 服务文件..." SERVICE_FILE="/lib/systemd/system/redis-server.service" cp "$SERVICE_FILE" "${SERVICE_FILE}.bak.$(date +%F-%H%M)" # 修正后的 Systemd 适配逻辑 echo " 适配 systemd 服务文件 (直接替换路径)..." SERVICE_FILE="/lib/systemd/system/redis-server.service" cp "$SERVICE_FILE" "${SERVICE_FILE}.bak.$(date +%F-%H%M)" # 1. 替换数据目录路径 (转义路径中的 / 以适配 sed) ESCAPED_DB_DIR=$(echo "$DB_DIR" | sed 's/[\/&]/\\&/g') sed -i "s|ReadWriteDirectories=-/var/lib/redis|ReadWriteDirectories=-${ESCAPED_DB_DIR}|g" "$SERVICE_FILE" # 2. 替换日志目录路径 ESCAPED_LOG_DIR=$(echo "$LOG_DIR" | sed 's/[\/&]/\\&/g') sed -i "s|ReadWriteDirectories=-/var/log/redis|ReadWriteDirectories=-${ESCAPED_LOG_DIR}|g" "$SERVICE_FILE" systemctl daemon-reload echo "✅ systemd 配置已更新" # ========================================== # 6. 启动与验证 # ========================================== echo " 启动 Redis..." systemctl stop redis-server || true systemctl enable --now redis-server haproxy sleep 2 if systemctl is-active --quiet redis-server; then echo "✅ Redis 启动成功!" if redis-cli -a "$REDIS_PASSWORD" ping 2>/dev/null | grep -q "PONG"; then echo "✅ 连接测试通过 (PONG)" else echo "⚠️ 连接测试失败,请检查日志" fi echo "==========================================" echo " 部署完成! 数据目录: $DB_DIR" echo "==========================================" else echo "❌ 启动失败! 查看日志:" tail -n 30 "$LOG_DIR/redis-server.log" 2>/dev/null || journalctl -u redis-server -n 30 exit 1 fi