crontab调用redis-cli bgsave“看似成功实则没备份”因bgsave异步返回ok不保证写完、path缺失致命令找不到、直接cp运行中dump.rdb易拷贝损坏文件;正确做法是用redis-cli --rdb生成带时间戳的独立rdb并校验上传。

crontab调用redis-cli bgsave为什么总“看似成功实则没备份”
因为bgsave只是触发异步保存,返回OK不代表文件已写完;crontab默认环境缺失PATH,可能根本找不到redis-cli;更关键的是,若脚本紧接着就cp /var/lib/redis/dump.rdb,大概率拷的是上一轮残留或正在重写的损坏文件。
必须用redis-cli --rdb生成带时间戳的独立RDB文件
直接cp运行中的dump.rdb风险极高。正确做法是让Redis主动写一个全新、带时间戳、不覆盖原文件的快照:
redis-cli -h 127.0.0.1 -p 6379 --rdb /backup/rdb/redis-$(date -u +%Y%m%dT%H%M%SZ).rdb- 该命令会阻塞直到写入完成,无需额外轮询
rdb_last_save_time - 路径必须不在Redis的
dir配置目录下(如/var/lib/redis),否则磁盘满时Redis和备份一起挂
上传前必须校验+打标签,不能只传.rdb
对象存储上传中断或网络丢包会导致文件截断,仅靠HTTP状态码200无法判断内容完整性:
- 上传前立即生成校验文件:
sha256sum /backup/rdb/redis-20261019T133000Z.rdb > /backup/rdb/redis-20261019T133000Z.rdb.sha256 - 上传时加元数据标签,例如AWS S3用
--tagging "redis_version=7.2.4&backup_time=20261019T133000Z" - 避免用
aws s3 cp裸传——改用aws s3 sync --delete配合生命周期策略自动清理过期备份
crontab条目要显式声明环境变量和完整路径
默认shell环境极简,redis-cli、date、aws等命令都可能找不到:
- 在crontab里写成:
0 * * * * PATH=/usr/local/bin:/usr/bin:/bin HOME=/root /usr/local/bin/redis-disaster-backup.sh - 脚本内所有命令用绝对路径:
/usr/bin/redis-cli、/usr/bin/date、/usr/local/bin/aws - 不要依赖
~或$HOME,硬编码/root/.aws/credentials或用--profile指定
异地灾备真正的难点不在“传出去”,而在于“能确认它真能恢复”。每次上传后,应记录master_repl_offset并存入元数据——这决定了后续能否用AOF片段做增量追平。没有这个偏移量,RDB冷备就只是个时间点快照,不是容灾方案。











