最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Redis如何定时备份RDB文件到远程服务器?
时间:2026-08-25 09:51:49 编辑:袖梨 来源:一聚教程网
不能只靠SAVE或BGSAVE完成备份,因二者仅生成无时间戳、不跨机、不清理旧文件的本地快照;需结合crontab调用脚本实现触发快照、等待完成、带时间戳拷贝校验、上传及定期清理。
不能只靠 SAVE 或 BGSAVE 命令就认为备份完成了——它们只生成本地快照,不带时间戳、不跨机、不清理旧文件,更不会自动上传到远程服务器。
为什么直接 crontab 调用 BGSAVE 不够用
很多脚本只写 redis-cli bgsave 就以为万事大吉,但实际会遇到这些问题:
-
BGSAVE成功后,dump.rdb仍留在 Redis 的dir目录(如/var/redis/6379/),同名覆盖,无历史版本 - 没做原子拷贝,若恰好在
cp过程中BGSAVE正在写入新 RDB,可能复制出损坏文件(虽然 Redis 用临时文件 + rename 保证原子性,但外部cp仍需避开写入窗口) - 没验证 RDB 文件是否可读,
cp完就走,结果传了个空文件或截断文件过去 - 没处理 SSH 密钥、权限、路径不存在等远程传输失败场景,crontab 日志里只看到
scp: Connection refused却没人发现
如何安全地定时拷贝并上传带时间戳的 RDB
核心是三步:触发快照 → 等待完成 → 拷贝+重命名+校验 → 上传。关键不是“立刻 cp”,而是等 BGSAVE 真正结束。
- 先用
redis-cli bgsave触发,再用redis-cli lastsave拿到上一次成功快照的 Unix 时间戳,轮询对比确认完成(避免sleep 2这种不可靠等待) - 用
date +%Y%m%d%H%M%S生成唯一文件名,例如dump-20260713110522.rdb,避免覆盖 - 拷贝后立即执行
redis-check-rdb /path/to/copy.rdb,返回非 0 就中止上传,防止传坏文件 - 上传用
rsync -avz --remove-source-files比scp更稳妥:支持断点续传、失败不删源、可加--timeout=30 - 远程目标路径建议按日期分层,如
user@backup-server:/backup/redis/2026/07/13/,方便按月归档和清理
crontab 和脚本怎么写才不出错
常见错误是把所有逻辑塞进一行 crontab,或忽略 shell 环境差异(crontab 默认 $PATH 极简)。正确做法:
- crontab 只调用完整路径的脚本:
0 * * * * /usr/local/redis/copy/upload_rdb_hourly.sh,不写sh前缀 - 脚本开头必须声明解释器和环境:
#!/bin/bash+export PATH="/usr/local/bin:/usr/bin:/bin" - Redis 配置里要明确
dir和dbfilename,别依赖默认值;用redis-cli CONFIG GET dir和CONFIG GET dbfilename动态获取,而非硬编码/var/redis/6379/dump.rdb - 远程用户需提前配置免密 SSH(
ssh-copy-id),且远程目录存在、有写权限;脚本里用mkdir -p创建父目录,但不要用sudo—— crontab 以 redis 用户运行,不该提权 - 每小时备份保留 48 份,但清理逻辑放在上传之后,避免因网络失败导致误删本地最新副本
真正麻烦的不是写脚本,而是验证上传后的 RDB 能否被 redis-check-rdb 读通、能否在另一台机器上用 redis-server --test-memory 加载成功——这些必须定期抽样测,不能只看 crontab 日志里有没有报错。