Redis 数据备份与恢复的核心是持久化机制。持久化解决的是进程退出后内存数据丢失的问题,而备份与恢复则进一步解决机器宕机、磁盘损坏、误删数据等场景。很多团队在搭建 Redis 时只关心读写性能,直到一次主从切换或重启操作后才意识到数据没有落盘。理解备份与恢复首先要理解 RDB 和 AOF 两条主线。

RDB与AOF的工作机制差异
RDB 快照通过 fork 子进程将当前内存数据写入一个二进制文件,默认文件名是 dump.rdb。触发方式包括手动执行 SAVE 或 BGSAVE,以及配置项 save 900 1 这类自动触发条件。SAVE 会阻塞主线程,生产环境几乎不用;BGSAVE 通过子进程异步完成,但在 fork 瞬间如果内存很大,也可能出现短暂的阻塞。RDB 的优点是文件紧凑、恢复速度快,适合做冷备份;缺点是快照之间发生宕机会丢失最后一次快照之后的所有写操作。
AOF 日志则记录每一次写命令,默认关闭。开启后 Redis 将写命令追加到文件末尾,并按照 appendfsync 策略决定同步时机:always 每条命令刷盘,数据最安全但性能差;everysec 每秒刷盘,最多丢一秒数据;no 由操作系统决定,性能最好但安全性最低。AOF 文件会不断增长,Redis 通过重写机制压缩体积,例如 auto-aof-rewrite-percentage 100 和 auto-aof-rewrite-min-size 64mb。AOF 可读性更好,恢复时逐条重放命令,但文件通常比 RDB 大,恢复速度也慢。
还有一种混合持久化方式,在 Redis 4.0 之后可以通过 aof-use-rdb-preamble yes 开启。重写后的 AOF 文件头部是 RDB 格式,后面追加增量的 AOF 日志,兼顾恢复速度和数据完整性。但要注意,如果 Redis 版本低于 4.0,不要贸然读取混合文件。
配置示例
# RDB 自动触发条件 save 900 1 save 300 10 save 60 10000 # AOF 开启与刷盘策略 appendonly yes appendfsync everysec # 混合持久化 aof-use-rdb-preamble yes
上面的配置表示 900 秒内至少 1 次写、300 秒内至少 10 次写、60 秒内至少 10000 次写时触发 BGSAVE。生产环境可以根据写入压力调整阈值,但不建议完全关闭 RDB。
备份与恢复的操作流程
备份操作前需要确认持久化目录和文件名。执行 CONFIG GET dir 可以查看 RDB 和 AOF 文件所在目录,执行 CONFIG GET dbfilename 查看 RDB 文件名。最直接的备份方式是把这些文件复制到其他磁盘或对象存储,推荐使用 BGSAVE 生成新的 RDB 后再复制。原因是直接复制正在写入的 RDB 文件可能得到不一致的快照。对于 AOF,可以先执行 BGREWRITEAOF 让文件处于较新且相对稳定的状态,再复制。
下面是一个简单的备份脚本,使用 redis-cli 触发 BGSAVE,等待子进程完成后将文件复制到备份目录,并记录最近一次成功保存时间。
#!/bin/bash
REDIS_CLI="/usr/local/bin/redis-cli"
BACKUP_DIR="/data/redis_backup"
DATE=$(date +%F_%H-%M-%S)
# 触发后台快照
$REDIS_CLI BGSAVE >/dev/null
# 等待快照完成
while [ $($REDIS_CLI INFO persistence | grep rdb_bgsave_in_progress | cut -d: -f2 | tr -d '\r') -eq 1 ]; do
sleep 1
done
# 获取持久化目录和文件名
DIR=$($REDIS_CLI CONFIG GET dir | tail -1)
RDB_FILE=$($REDIS_CLI CONFIG GET dbfilename | tail -1)
mkdir -p $BACKUP_DIR/$DATE
cp $DIR/$RDB_FILE $BACKUP_DIR/$DATE/
echo "Backup completed at $DATE" >> $BACKUP_DIR/backup.log
脚本中 INFO persistence 返回的 rdb_bgsave_in_progress 字段为 0 表示快照完成。复制完成后建议将备份文件上传到异地,防止本机磁盘故障同时损坏原文件和备份。恢复流程则要谨慎:先停止 Redis 写入,确认要恢复的文件版本,再替换目录中的 RDB 或 AOF 文件,最后启动 Redis。如果同时开启了 RDB 和 AOF,默认会优先加载 AOF 文件,因为 AOF 通常更新更完整。
恢复后不要立刻对外提供服务,先使用 INFO keyspace 检查键数量,再执行几条抽样读取命令,必要时用 redis-check-rdb dump.rdb 或 redis-check-aof --fix appendonly.aof 检查文件完整性。如果 AOF 文件有损坏,redis-check-aof 可以尝试修复,但修复过程可能删除尾部不完整命令,因此不能作为唯一恢复手段。
高频误区与避坑建议
最大的误区是把主从复制当成备份。主从复制解决的是高可用和读扩展问题,主节点执行一条 FLUSHALL 或误删数据后,从节点也会同步执行同样的删除操作。也就是说灾难会在主从之间传播,主从架构并不能替代定期备份。另一个常见问题是只开启 RDB 而关闭 AOF,线上写入频率高的场景下,两次快照之间的数据全部依赖内存,一旦宕机丢失量可能远超预期。RDB 默认条件可能十几分钟才触发一次,因此不建议只依赖 RDB。
AOF 也有自己的坑。开启 AOF 后如果不设置重写阈值,文件可能膨胀到几十 GB,恢复时重放命令耗时很长,而且占用大量磁盘 IO。更隐蔽的是 AOF 刷盘策略设置为 everysec 时,操作系统缓存中存在尚未刷盘的数据,机器断电仍可能丢失最后一秒的写入。如果业务对数据丢失零容忍,应使用 appendfsync always,但需要接受写入吞吐明显下降。
还有一个经常被忽略的问题是备份文件不验证。很多团队配置了定时备份脚本,却从没做过恢复演练。直到真正需要恢复时发现文件权限错误、备份目录磁盘写满、脚本中的 BGSAVE 一直失败但告警未配置。建议每季度至少做一次全流程恢复演练,将备份文件恢复到独立的测试 Redis 实例,校验键数量和关键数据。恢复演练中还要注意磁盘空间,RDB 文件大小通常接近内存数据大小,如果数据量很大,需要预留足够空间。
最后提醒,恢复操作期间应停止新写入,避免恢复后的数据又被新请求覆盖。如果无法停写,可以考虑先恢复到一个新实例,再通过数据比对或双写切换,而不是直接覆盖线上目录。数据保护没有一劳永逸的配置,只有持续的验证和调整。