13 10 月 2026

Redis 是内存数据库,重启后数据会不会丢,完全取决于持久化配置。配错了,断电一次全没了;配对了,鱼和熊掌可以兼得。

这篇讲 RDB 和 AOF 两种持久化机制的原理、怎么配、怎么选,以及 Redis 7 的多机持久化新特性。

需要云服务器可以看看财富云计算:NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,一键开服面板,主流游戏快速部署。

一、两种持久化是什么

机制原理文件恢复速度数据安全性
RDB定时把内存数据快照写成二进制文件dump.rdb快(直接加载)可能丢几分钟数据
AOF把每条写命令追加到日志文件appendonly.aof慢(重放命令)最多丢 1 秒

比喻:RDB 是拍照(某个瞬间的完整状态),AOF 是录像(每个动作都记下来)。恢复时,照片直接看,录像要重新演一遍。

二、RDB 快照配置

触发方式

# /etc/redis/redis.conf

# 自动触发: 60 秒内至少 1 次写入就快照
save 900 1       # 900 秒(15分钟)内 1 次写入
save 300 10      # 300 秒(5分钟)内 10 次写入
save 60 10000    # 60 秒内 10000 次写入

# 关掉 RDB(只用 AOF 时)
# save ""

# 文件位置和命名
dir /var/lib/redis
dbfilename dump.rdb

手动触发:

# 阻塞式(会卡住其他请求,生产慎用)
redis-cli -a 密码 save

# 后台异步(推荐,fork 子进程写盘)
redis-cli -a 密码 bgsave

# 看 RDB 最后一次保存信息
redis-cli -a 密码 info persistence

bgsave 的原理与坑

bgsave 用 fork() 创建子进程写 RDB,主进程继续服务。问题在 fork:

  • fork 时内存要复制页表,数据量大时 fork 本身可能耗时几十到几百毫秒(这期间请求阻塞)
  • 如果 vm.overcommit_memory=0,fork 可能因内存不足失败(报 Background saving terminated with error)
# 解决:允许 overcommit
echo 'vm.overcommit_memory=1' >> /etc/sysctl.d/99-redis.conf
sysctl -p /etc/sysctl.d/99-redis.conf

更多内核调优见内核参数优化 sysctl。

三、AOF 日志配置

开启 AOF

# /etc/redis/redis.conf
appendonly yes
appendfilename "appendonly.aof"

# 文件位置(默认和 dir 一致)
dir /var/lib/redis

# 同步策略(核心三选一)
appendfsync everysec      # 每秒同步一次(推荐,折中方案)
# appendfsync always      # 每次写都同步(最安全,最慢)
# appendfsync no          # 让系统决定(最快,最危险)

# AOF 重写(压缩文件,消除冗余命令)
auto-aof-rewrite-percentage 100    # 比上次重写后大 100% 时触发
auto-aof-rewrite-min-size 64mb     # 至少 64M 才重写

# 混合持久化(Redis 4.0+,强烈推荐)
aof-use-rdb-preamble yes

三个同步策略怎么选

策略安全性性能适用
always每条命令落盘,最多丢 0 条慢(受磁盘 IO 限制)金融、支付,不能丢一条
everysec最多丢 1 秒快(异步刷盘)绝大多数场景
no丢多少看系统最快缓存场景,丢了就重新算

AOF 重写机制

AOF 文件会无限增长(同样的 key 被 set 一万次,文件里就有一万条命令)。重写(rewrite)把当前内存状态写成一份紧凑的新 AOF:

# 手动触发重写
redis-cli -a 密码 bgrewriteaof

# 看重写状态
redis-cli -a 密码 info persistence | grep aof_rewrite

重写不会丢数据:重写期间的新写命令会缓存在 buffer,重写完后追加进去。混合持久化(aof-use-rdb-preamble yes)让新 AOF 的前半段是 RDB 格式——恢复更快,文件更小。

四、恢复数据

Redis 启动时自动加载:

  1. 开了 AOF:只加载 AOF(更完整,忽略 RDB)
  2. 只开 RDB:加载 dump.rdb
  3. 都没开:空库启动

手动指定恢复文件:

# 把备份文件放到配置的 dir 下
cp /backup/dump-20261013.rdb /var/lib/redis/dump.rdb
chown redis:redis /var/lib/redis/dump.rdb

# 重启(如果 appendonly yes,要先关掉 AOF 或用 RDB 覆盖 appendonly 目录)
systemctl restart redis

# 验证
redis-cli -a 密码 dbsize

从 AOF 恢复:

# 确认 appendonly yes
cp /backup/appendonly-20261013.aof /var/lib/redis/appendonly.aof
systemctl restart redis

灾难恢复:AOF 损坏

# AOF 文件末尾损坏时,Redis 可能拒绝启动
# 用 redis-check-aof 修复(会丢弃损坏的末尾命令)
redis-check-aof --fix /var/lib/redis/appendonly.aof

五、RDB vs AOF 怎么选

决策表

场景推荐配置理由
纯缓存(丢了能重建)只 RDB,甚至全关性能优先
一般业务(会话、配置)RDB + AOF everysec平衡
不能丢数据(队列、计数)RDB + AOF always安全优先
大内存实例(几十 G)RDB + AOF everysec + 混合重写开销大,调大 min-size
主从架构全开(从库负责兜底)主库崩了切从库

Redis 7 的多机持久化(新特性)

Redis 7 开始支持多个持久化副本,AOF 文件可以同时写到多个位置:

# 主 AOF 写本地,副本写网络位置(比如 NAS)
appendfsync everysec
aof-primary-dir /var/lib/redis
aof-secondary-dir 1 redis://user:pass@nas.local:6379

作用是本地磁盘坏了,数据在另一台机器上还有一份。对单机部署的 Redis 是个不错的容灾增强。

六、持久化对性能的影响

操作影响
save(阻塞)大数据量时阻塞主线程,请求全卡
bgsavefork 瞬间卡几十 ms;写盘期间吃磁盘 IO
AOF everysec每秒一次 fsync,影响很小
AOF always每次写都 fsync,QPS 可能掉一个数量级
AOF 重写fork + 写新文件,重写期间 IO 高

游戏服/高并发场景注意:持久化的 IO 可能让游戏服卡顿。对策:

# 1. 持久化文件放 SSD,别放机械盘
dir /var/lib/redis    # 确认这是 SSD 分区

# 2. 降低持久化优先级(ionice)
# systemd 单元里加:
IOSchedulingClass=idle
IOSchedulingPriority=7

# 3. RDB 保存频率别太高(缓存场景)
save 3600 1    # 一小时一次都行

七、配置文件模板

整合版,按需取:

# ===== 持久化 =====
# RDB
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes     # bgsave 失败时拒绝写入(防数据继续丢)
rdbcompression yes                  # 压缩 RDB
rdbchecksum yes                     # RDB 校验和(防文件损坏)
dbfilename dump.rdb
dir /var/lib/redis

# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes        # 重写时不阻塞主进程 fsync
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes             # 混合持久化
aof-load-truncated yes               # 加载时截断损坏的末尾(能启动优先)

# ===== 内存 =====
maxmemory 2gb
maxmemory-policy allkeys-lru

改完重启验证:

systemctl restart redis
redis-cli -a 密码 info persistence
# 关注: rdb_last_bgsave_status:ok, aof_enabled:1, aof_last_write_status:ok

八、常见问题

Q:重启 Redis 数据全没了?
save "" + appendonly no,持久化全关了。检查配置,至少开一个。

Q:aof_last_write_status:err?
磁盘满了或权限问题。df -h 看磁盘,ls -la /var/lib/redis/ 看 redis 用户有没有写权限。

Q:bgsave 失败,日志报 fork: Cannot allocate memory?
overcommit 问题,设 vm.overcommit_memory=1(见上文)。

Q:AOF 文件好几个 G,正常吗?
没触发重写。检查 auto-aof-rewrite-min-size 和百分比配置,或手动 bgrewriteaof。

Q:RDB 和 AOF 内容不一致,以谁为准?
Redis 启动时优先 AOF。因为 AOF 记录更完整。想让 RDB 生效,先关 AOF。

Q:持久化文件要备份吗?
要!备份方法和数据库一样:定期把 dump.rdb 和 appendonly.aof 打包外传。见MySQL 备份与恢复实战里的策略。

小结

持久化配置就三句话:一般场景 RDB + AOF everysec;纯缓存只留 RDB;不能丢数据上 AOF always。混合持久化(aof-use-rdb-preamble yes)白捡的好处,无脑开。配完用 info persistence 确认状态全 ok,再定期备份文件到异地。

更多数据库教程见财富云计算知识库:Redis 缓存实战、MySQL 优化、Redis 安全加固、MySQL 备份全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:MySQL 备份与恢复实战:dump、binlog 时间点恢复、演练
  2. 下一篇:Docker 部署游戏服务器实战:帕鲁、方舟、我的世界容器化
发表评论 2

取消回复