直接用 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:在从节点上执行备份
备份操作(bgsave或redis-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}"
🔐 关于密码的额外建议
不要将密码硬编码在脚本中(尤其是脚本可能被多人查看或上传到代码仓库)。
更安全的做法是从环境变量或单独的配置文件中读取,例如:# 从环境变量读取 REDIS_PASSWORD="${REDIS_PASSWORD:-}" # 或者从只有只读权限的配置文件读取 source /etc/redis_backup.conf测试密码是否正确
可以先手动测试连接:redis-cli -h 127.0.0.1 -p 6379 --auth your_password_here PING如果返回
PONG则说明密码正确。密码包含特殊字符的处理
如果密码中包含$、&、*等特殊字符,请使用单引号包裹:REDIS_PASSWORD='my$ecure&p@ssw0rd'
📌 使用说明
- 将脚本保存为
redis_backup.sh - 修改脚本中的
BACKUP_DIR、REDIS_HOST、REDIS_PORT、REDIS_PASSWORD - 赋予执行权限:
chmod +x redis_backup.sh - 手动测试:
./redis_backup.sh - 添加到 crontab 实现定时备份(例如每天凌晨2点):
0 2 * * * /path/to/redis_backup.sh >> /var/log/redis_backup.log 2>&1
这样修改后,备份操作会自动使用密码认证,同时保证 RDB 文件的一致性(因为 --rdb 命令会等待快照生成完毕后才退出)。