什么是持久化
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:
-
停止 Redis
-
将
dump.rdb放到配置的dir目录 -
启动 Redis
恢复 AOF:
-
停止 Redis
-
放置
appendonly.aof -
若文件损坏可修复:
redis-check-aof --fix appendonly.aof -
启动 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)
兼具:
-
安全性
-
性能
-
恢复速度