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)

兼具:

  • 安全性

  • 性能

  • 恢复速度

相关推荐
二宝哥12 小时前
CentOS 7.9 系统下 Redis 5.0.4 单机安装与源码编译安装指南
redis·centos
ShiXZ21318 小时前
Redis docker-compose 部署指南
redis·docker·eureka
青山木21 小时前
Redis 缓存一致性全解:从 Cache Aside 到延迟双删、Canal+MQ 的进阶之路
java·数据库·redis·后端·缓存
YDS8291 天前
大营销平台 —— 活动SKU库存扣减业务及其一致性处理
java·spring boot·redis·rabbitmq·ddd
爬也要爬着前进2 天前
redis主从搭建
数据库·redis·缓存
用户095367515832 天前
在系统的学习 redis 前的疑惑
redis·go
吴声子夜歌2 天前
Redis 3.x——集群故障转移
java·数据库·redis·集群
明豆2 天前
Redis 分布式缓存生产实战
redis·分布式·缓存
海兰2 天前
【高速缓存】RedisVL 指南:从向量搜索到 AI 应用落地
人工智能·redis
weixin_727535622 天前
双Token认证体系深度拆解:Spring Security + JWT + Redis
redis·spring·wpf