Redis 持久化机制:RDB 和 AOF

什么是持久化

Redis 是内存数据库,数据全部存储在内存中,因此一旦:

  • Redis 进程崩溃

  • 系统断电

  • 操作系统重启

内存数据会全部丢失。

为解决这个问题,Redis 提供了两种持久化方式:

1. RDB(快照 Snapshot)

  • 把某个时间点的内存数据完整写入磁盘

  • 生成 dump.rdb

适合用于冷备、主从同步、定期备份。

2. AOF(Append Only File)

  • 以日志的方式记录所有写操作(set/incr/...)

  • 通过重放日志恢复数据

适合追求数据最小丢失的场景。


RDB(快照持久化)

RDB工作原理

Redis 会在某个时间点把当前内存数据做一份快照保存到磁盘:

生成的文件:

复制代码
dump.rdb

采用二进制格式,体积较小,恢复速度快。


SAVE vs BGSAVE

我们可以主动使用命令save和bgsave进行持久化

SAVE(阻塞式)

复制代码
SAVE
  • 由主线程执行

  • 会阻塞 Redis,直到操作完成(不推荐)

BGSAVE(后台执行)

复制代码
BGSAVE
  • Redis 主线程 fork 出子进程

  • 子进程把数据写入 dump.rdb

  • 主线程继续处理业务读写(推荐)

主进程如果在 fork() 子进程之后继续写入新的数据,不会影响正在生成的 RDB 文件内容,但会产生额外的内存开销(Copy-On-Write 机制导致)

Redis 使用 Linux 的 Copy-On-Write(COW) 技术:

  • fork 后,父子进程共享相同的内存页(不复制)

  • 只有当主进程写某个 key 时,该内存页才会被复制

这意味着:

1. 子进程能继续使用"原来的旧内存页"写 RDB

2. 主进程则在写入时复制内存页,不影响子进程

如果 BGSAVE 期间写入量很大:

  • 会触发大量的内存页复制

  • Redis 内存使用可能短时间上升

举例:

如果 1GB 的数据中有 200MB 在 BGSAVE 期间被修改

→ Redis 需要额外复制 200MB

这是 BGSAVE 的主要代价。所以高写入业务:谨慎使用频繁 RDB


自动触发规则

redis.conf 中:

复制代码
save 900 1        # 900 秒内至少 1 次写操作
save 300 10       # 300 秒内至少 10 次写操作
save 60 10000     # 60 秒内至少 10000 次写操作

含义:满足任意一个条件都会触发 RDB。

禁用 RDB:

复制代码
save ""

RDB 文件位置与配置

redis.conf 中:

复制代码
dbfilename dump.rdb          # 文件名
dir /var/lib/redis           # 保存目录

查看运行时目录:

复制代码
CONFIG GET dir

RDB 优缺点

优点

  • 恢复速度快(文件小)

  • 对性能影响小(fork + 子进程写)

  • 文件适合作为冷备、主从同步

缺点

  • 不够实时,可能丢失几分钟数据

  • 文件为二进制,无法阅读

  • fork 过程中需要额外内存


AOF(追加日志持久化)

AOF工作原理

AOF 会把 Redis 的写命令追加记录到文件中:

复制代码
SET a 1
INCR b
LPUSH list 10

日志文件:

复制代码
appendonly.aof

Redis 重启时,按日志顺序重放命令恢复数据。


AOF 写回策略

配置项:

复制代码
appendfsync always
appendfsync everysec
appendfsync no

1. always

  • 每条写命令都 fsync,数据最安全

  • 性能最差

2. everysec(默认)

  • 每秒 fsync 一次

  • 性能与安全性折中

  • 最常用

3. no

  • 不主动 fsync,交给操作系统

  • 性能最好,安全性最差


AOF 文件位置与配置

在 redis.conf 中打开 AOF:

复制代码
appendonly yes
appendfilename "appendonly.aof"
dir /var/lib/redis

AOF 重写机制(Rewrite)

随着运行时间增加,AOF 会变得很大,比如:

复制代码
SET a 1
SET a 2
SET a 3

同一个key多次重复set,其实我们只需要保留最后一个就可以,前面的命令没有必要保留,rewrite机制仅保留必要命令:

复制代码
SET a 3

Redis 会:

  • fork 出子进程

  • 子进程根据当前内存数据生成一个更小的 AOF 文件

  • 不影响主线程处理请求

相关配置:

复制代码
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

含义:

  • 当 AOF 文件大小超过上次重写后大小的 100% 且至少 64MB

    → 触发自动重写


AOF 优缺点

优点

  • 最安全的持久化方式(最多丢失 1 秒)

  • 文本日志,可读、可手工修改

  • 重写机制减少文件大小

缺点

  • 文件普遍比 RDB 大

  • 恢复速度慢(需要重放大量命令)

  • 写性能比 RDB 开销更大


RDB 与 AOF 对比总结

特性 RDB AOF
数据安全性 可能丢失几分钟 最多丢失 1 秒
性能影响 中等
文件大小
恢复速度
可读性 不可读 可读
使用场景 定期冷备、主从同步 高安全、高可靠

RDB + AOF 混合持久化

Redis 支持同时启用:

复制代码
save 900 1
appendonly yes
appendfsync everysec

Redis 重启时优先使用 AOF 恢复(因为数据更新更新)。

这种组合:

  • RDB 作为完整快照

  • AOF 作为增量日志

  • 兼具速度与安全性


持久化文件恢复流程

恢复 RDB:

  1. 停止 Redis

  2. dump.rdb 放到配置的 dir 目录

  3. 启动 Redis

恢复 AOF:

  1. 停止 Redis

  2. 放置 appendonly.aof

  3. 若文件损坏可修复:

    复制代码
    redis-check-aof --fix appendonly.aof
  4. 启动 Redis

同时存在 RDB + AOF:

  • Redis 会优先 AOF 恢复

原因:数据更新更实时。


常见问题 FAQ

1. RDB 会阻塞 Redis 吗?

  • SAVE 会

  • BGSAVE 不会(使用子进程)

2. AOF 重写会阻塞吗?

不会,重写过程由子进程执行。

3. AOF 文件损坏怎么办?

复制代码
redis-check-aof --fix

4. RDB 文件损坏怎么办?

无法修复,只能使用备份。

5. 启用 AOF 会影响性能吗?

会有一定影响,但一般可接受,尤其是 everysec 策略。


总结

Redis 提供两种持久化方式:

RDB

  • 易于备份

  • 性能好

  • 快速恢复

AOF

  • 数据最安全

  • 可读可编辑

  • 更适合生产环境

推荐组合使用:

RDB + AOF(everysec)

兼具:

  • 安全性

  • 性能

  • 恢复速度

相关推荐
忍冬行者8 小时前
清理三主三从redis集群的过期key和键值超过10M的key
数据库·redis·缓存
TimberWill8 小时前
使用Redis队列优化内存队列
数据库·redis·缓存
川石课堂软件测试11 小时前
Mysql中触发器使用详详详详详解~
数据库·redis·功能测试·mysql·oracle·单元测试·自动化
gugugu.12 小时前
Redis Set类型完全指南:无序集合的原理与应用
数据库·windows·redis
feathered-feathered14 小时前
Redis基础知识+RDB+AOF(面试)
java·数据库·redis·分布式·后端·中间件·面试
花月C15 小时前
基于Redis的BitMap数据结构实现签到业务
数据结构·数据库·redis
梦里不知身是客1115 小时前
redis的缓存击穿原因
redis·缓存·bootstrap
理人综艺好会17 小时前
Redis学习之go-redis
redis·学习·golang
不穿格子的程序员19 小时前
Redis篇4——Redis深度剖析:内存淘汰策略与缓存的三大“天坑”
数据库·redis·缓存·雪崩·内存淘汰策略
gugugu.19 小时前
Redis List类型完全指南:从原理到实战应用
数据库·redis·list