直接用 cp 命令复制正在运行的 RDB 文件,确实会导致备份不完整[reference:0]。要解决这个问题,核心原则是:永远只备份处于“静止”状态的 RDB 文件。

这里有几种方法,从简单可靠到更专业,你可以根据场景选择。

⚙️ 方法一:手动触发并复制

主动让Redis创建一个新的快照,然后复制它。这种方法简单可靠,适合手动或低频率的自动化备份。

  • 步骤 1:触发快照
    使用 bgsave 命令在后台生成一个新的 RDB 文件:

    redis-cli BGSAVE
  • 步骤 2:等待并确认完成
    Redis 会返回 Background saving started。你需要等待它完成,可以执行 info persistence 检查 rdb_bgsave_in_progress 字段,当它的值变为 0 时,表示生成完毕[reference:1]。

  • 步骤 3:复制文件
    生成完成后,就可以安全地复制文件了。

    # 找到 RDB 文件的存放目录
    redis-cli CONFIG GET dir
    # 复制文件到你指定的备份路径
    cp /var/lib/redis/dump.rdb /path/to/backup/dump-$(date +%Y%m%d%H%M%S).rdb

🚀 方法二:使用 redis-cli --rdb 命令

redis-cli --rdb 命令会直接将此刻的数据生成一个 RDB 文件并保存到指定位置,生成后即可用于备份。它操作更直接,一步到位[reference:2]。

redis-cli --rdb /path/to/backup/dump-$(date +%Y%m%d%H%M%S).rdb

执行这个命令时,Redis 会生成一个全新的 RDB 文件,并在生成完成后自动断开连接,非常方便。

☁️ 方法三:设置从节点备份(主从复制)

如果你有主从架构,推荐在从节点上执行备份,这样完全不会影响主节点性能,适合对性能要求高的生产环境。

  • 步骤 1:设置从节点
    通过 replicaof 命令或配置文件,将备份节点设为从库:

    redis-cli REPLICAOF <master_ip> <master_port>
  • 步骤 2:等待数据同步
    等待从节点完成与主节点的数据同步。

  • 步骤 3:在从节点上执行备份
    备份操作(bgsaveredis-cli --rdb)在从节点上执行即可。

⚡️ 方法四:AOF 与 RDB 结合

AOF 文件记录了所有写操作,实时性好。备份时,同时备份 RDB 和 AOF 文件,能实现更优的数据恢复点(RPO)[reference:3]。

# 触发 AOF 重写,优化文件大小
redis-cli BGREWRITEAOF

之后,同时备份 RDB 文件和 AOF 文件:

cp /var/lib/redis/appendonly.aof /path/to/backup/appendonly-$(date +%Y%m%d%H%M%S).aof
cp /var/lib/redis/dump.rdb /path/to/backup/dump-$(date +%Y%m%d%H%M%S).rdb

恢复时,先载入 RDB,再重放 AOF,能最大程度恢复数据[reference:4]。

📝 自动化备份脚本示例 (Bash)

你可以将这个脚本加入 crontab 定时任务,实现自动化备份。

#!/bin/bash
# Redis 备份脚本

# 配置
BACKUP_DIR="/path/to/backup/dir"
REDIS_HOST="127.0.0.1"
REDIS_PORT="6379"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/redis_${TIMESTAMP}.rdb"

# 1. 执行备份并等待完成
echo "Starting RDB backup for ${REDIS_HOST}:${REDIS_PORT}"
redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} --rdb ${BACKUP_FILE} || { echo "Backup failed!"; exit 1; }

# 2. 计算并保存校验和
sha256sum ${BACKUP_FILE} > ${BACKUP_FILE}.sha256

# 3. 清理超过 30 天的旧备份
find ${BACKUP_DIR} -name "redis_*.rdb" -type f -mtime +30 -delete
find ${BACKUP_DIR} -name "redis_*.rdb.sha256" -type f -mtime +30 -delete

echo "Backup completed: ${BACKUP_FILE}"

确保脚本有执行权限:

chmod +x /path/to/your_script.sh

然后添加到 crontab

0 2 * * * /path/to/your_script.sh >> /var/log/redis_backup.log 2>&1

🛡️ 最佳实践与注意事项

  • 异地与云存储:将备份文件传输到云存储(如 AWS S3)或另一台服务器,能有效防范本地灾难[reference:5]。
  • 校验和:备份后生成一个校验和(如 SHA256),用于日后验证文件完整性[reference:6]。
  • 恢复演练:定期在隔离环境尝试恢复备份,这是验证备份是否真正可用的唯一标准[reference:7]。可以使用 redis-check-rdb 工具进行检查[reference:8]。
  • 存储位置:不建议将备份文件存放在 Redis 的数据目录(dir)下,避免因磁盘写满导致 Redis 异常[reference:9]。

自动化备份脚本示例 (Bash) redis是有密码

好的,针对 Redis 有密码的情况,修改后的自动化备份脚本如下。主要改动是增加了 REDIS_PASSWORD 变量,并通过 REDISCLI_AUTH 环境变量安全地传递密码,避免密码直接出现在命令行中。

#!/bin/bash
# Redis 备份脚本(支持密码认证)

# ==================== 配置区域 ====================
BACKUP_DIR="/path/to/backup/dir"          # 备份文件存放目录
REDIS_HOST="127.0.0.1"                    # Redis 主机
REDIS_PORT="6379"                         # Redis 端口
REDIS_PASSWORD="your_password_here"       # 请修改为你的 Redis 密码
TIMESTAMP=$(date +%Y%m%d_%H%M%S)          # 备份文件时间戳
BACKUP_FILE="${BACKUP_DIR}/redis_${TIMESTAMP}.rdb"
# =================================================

# 1. 执行备份并等待完成
echo "Starting RDB backup for ${REDIS_HOST}:${REDIS_PORT}"

# 使用 REDISCLI_AUTH 环境变量传递密码,比 -a 参数更安全(不会出现在进程列表中)
REDISCLI_AUTH="${REDIS_PASSWORD}" redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} --rdb ${BACKUP_FILE}
if [ $? -ne 0 ]; then
    echo "Backup failed!"
    exit 1
fi

# 2. 计算并保存校验和(用于日后验证文件完整性)
sha256sum ${BACKUP_FILE} > ${BACKUP_FILE}.sha256

# 3. 清理超过 30 天的旧备份
find ${BACKUP_DIR} -name "redis_*.rdb" -type f -mtime +30 -delete
find ${BACKUP_DIR} -name "redis_*.rdb.sha256" -type f -mtime +30 -delete

echo "Backup completed: ${BACKUP_FILE}"

🔐 关于密码的额外建议

  1. 不要将密码硬编码在脚本中(尤其是脚本可能被多人查看或上传到代码仓库)。
    更安全的做法是从环境变量或单独的配置文件中读取,例如:

    # 从环境变量读取
    REDIS_PASSWORD="${REDIS_PASSWORD:-}"
    # 或者从只有只读权限的配置文件读取
    source /etc/redis_backup.conf
  2. 测试密码是否正确
    可以先手动测试连接:

    redis-cli -h 127.0.0.1 -p 6379 --auth your_password_here PING

    如果返回 PONG 则说明密码正确。

  3. 密码包含特殊字符的处理
    如果密码中包含 $&* 等特殊字符,请使用单引号包裹:

    REDIS_PASSWORD='my$ecure&p@ssw0rd'

📌 使用说明

  1. 将脚本保存为 redis_backup.sh
  2. 修改脚本中的 BACKUP_DIRREDIS_HOSTREDIS_PORTREDIS_PASSWORD
  3. 赋予执行权限:chmod +x redis_backup.sh
  4. 手动测试:./redis_backup.sh
  5. 添加到 crontab 实现定时备份(例如每天凌晨2点):
    0 2 * * * /path/to/redis_backup.sh >> /var/log/redis_backup.log 2>&1

这样修改后,备份操作会自动使用密码认证,同时保证 RDB 文件的一致性(因为 --rdb 命令会等待快照生成完毕后才退出)。

文档更新时间: 2026-04-06 01:27   作者:月影鹏鹏
IT运维支持-AIWALY-月影工作室