redis的bgsave命令仅生成最新dump.rdb并覆盖旧文件,无法提供历史版本与恢复窗口;必须依赖外部脚本+crontab实现带时间戳拷贝、非空校验、超时等待及轮转清理,否则备份不可靠。

redis-cli 的 bgsave 命令本身不负责备份归档,它只生成一份最新的 dump.rdb 文件;真正的冷备份必须靠外部脚本 + crontab 定期拷贝、打时间戳、清理旧文件——否则你永远只有“最后一份”,根本谈不上恢复窗口。
为什么不能直接用 save 或 bgsave 当备份?
save 会阻塞 Redis 主进程,生产环境禁用;bgsave 虽然异步,但每次只覆盖 dump.rdb,没有历史版本。一旦写入失败或覆盖后发现数据异常,无从回退。
- Redis 启动时只加载最新
dump.rdb,不会识别带时间戳的备份文件 -
bgsave成功与否无法通过返回值可靠判断(它总是返回 OK,哪怕磁盘满) - 拷贝前必须确认文件已写完,否则可能复制到一个正在写入的半成品
每小时备份脚本的关键检查点
核心不是“复制”,而是“等写完再复制 + 精确清理”。下面这段逻辑缺一不可:
#!/bin/sh
REDIS_DATA_DIR="/var/lib/redis"
BACKUP_ROOT="/backup/redis/hourly"
DATE=$(date +%Y%m%d%H)
<h1>1. 触发后台保存</h1><p>redis-cli bgsave > /dev/null 2>&1</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3464" title="Redis Skill - 高性能缓存管理"><img
src="https://img.php.cn/upload/skill/000/000/081/178960683454849.jpg" alt="Redis Skill - 高性能缓存管理" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3464" title="Redis Skill - 高性能缓存管理" class="overflowclass">Redis Skill - 高性能缓存管理</a>
<p class="overflowclass">Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3464" title="Redis Skill - 高性能缓存管理" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><h1>2. 等待 dump.rdb 写入完成(最多10秒)</h1><p>for i in $(seq 1 10); do
[ -f "$REDIS_DATA_DIR/dump.rdb" ] && [ -s "$REDIS_DATA_DIR/dump.rdb" ] && break
sleep 1
done</p><h1>3. 拷贝并保留权限(-p)</h1><p>cp -p "$REDIS_DATA_DIR/dump.rdb" "$BACKUP_ROOT/$DATE.rdb"</p><h1>4. 清理 48 小时前的备份(注意:用 %Y%m%d%H 格式才匹配)</h1><p>DEL_DATE=$(date -d "48 hours ago" +%Y%m%d%H)
rm -f "$BACKUP_ROOT/${DEL_DATE}.rdb"</p>
- 必须用
-s检查dump.rdb是否非空,避免拷贝零字节文件 -
cp -p保留时间戳和权限,方便审计和恢复时校验 -
date -d "48 hours ago"比-d -48hour更可靠,兼容性更好 - 不要用
rm -rf删除单个文件,rm -f足够且更安全
crontab 定时规则与路径陷阱
crontab -e 中写的命令,运行环境没有用户 shell 的 PATH,所以必须写绝对路径:
- 错:
0 * * * * redis-cli bgsave→ 找不到命令 - 对:
0 * * * * /usr/bin/redis-cli bgsave - 脚本也一样:必须用
0 * * * * /bin/sh /backup/redis/hourly_backup.sh - Redis 数据目录路径要和
redis.conf中的dir配置一致,常见位置有/var/lib/redis、/usr/local/redis/data、/data
每日备份与小时备份如何共存不冲突?
两个脚本必须使用不同目录、不同时间格式、独立清理逻辑:
- 小时备份用
%Y%m%d%H(如2026052707.rdb),保留最近 48 个文件 - 每日备份用
%Y%m%d(如20260527.rdb),保留最近 30 个目录或文件 - 绝对不要让两个脚本往同一个目录写,否则
rm -f *.rdb可能误删 - 如果同时备份
appendonly.aof,注意它在bgsave期间可能被重写,应优先以 RDB 为准做冷备
最易被忽略的是:RDB 文件虽然“静态”,但它的生成依赖于 Redis 进程状态;如果脚本执行时 Redis 正在重启、OOM kill 或磁盘满,dump.rdb 可能根本没更新——所以定期校验备份文件的修改时间与大小,比单纯跑 cron 更关键。










