前言
Redis 的数据默认放在内存里,一旦进程重启数据就会丢失。为了保证数据不丢,Redis 提供了两种持久化机制:RDB 和 AOF。这篇笔记记录一下两者的原理、配置和踩坑经验。
RDB 持久化
RDB 是把某一时刻的内存数据快照写到一个二进制文件(默认 dump.rdb)里。
触发方式
save命令:主线程执行,会阻塞,生产环境基本不用bgsave命令:fork 出子进程异步写,主进程不阻塞- 配置自动触发,在
redis.conf中:
# 格式:save <秒> <修改次数>
save 900 1
save 300 10
save 60 10000
- 主从复制、
shutdown时也会触发
优点
- 文件紧凑,适合备份和容灾传输
- 恢复大数据集时比 AOF 快
缺点
- 无法做到实时持久化,两次快照之间的数据宕机会丢
- fork 子进程在数据量大时可能造成短暂卡顿
AOF 持久化
AOF 以追加的方式记录每一条写命令,重启时重放命令恢复数据。
开启方式
# redis.conf
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir" # Redis 7+ 存放目录
刷盘策略
# appendfsync always # 每条命令都刷盘,最安全最慢
appendfsync everysec # 每秒刷一次,默认,最多丢 1 秒数据
# appendfsync no # 交给操作系统,最快但最不安全
一般用 everysec 就够了。
AOF 重写
写命令越积越多,AOF 文件会膨胀,Redis 通过重写生成等价的最小命令集:
# 手动触发
bgrewriteaof
# 自动触发
auto-aof-rewrite-percentage 100 # 文件比上次重写后大 100%
auto-aof-rewrite-min-size 64mb # 且超过 64MB 才触发
优点
- 丢失数据少,最多丢 1 秒
- 文件是可读的命令文本,误操作(比如
flushall)还可以手动删掉那条命令再恢复
缺点
- 同等数据量文件比 RDB 大
- 恢复速度慢于 RDB
- 根据刷盘策略不同,有一定的性能开销
混合持久化(Redis 4.0+)
重写 AOF 时,先把当前内存状态以 RDB 格式写入 AOF 文件开头,之后的增量命令再用 AOF 格式追加:
aof-use-rdb-preamble yes # Redis 5.0+ 默认开启
这样恢复时大部分数据直接加载 RDB,速度快,同时增量部分又保证了低丢失,推荐开启。
RDB 与 AOF 对比
| 对比项 | RDB | AOF |
|---|---|---|
| 文件类型 | 二进制快照 | 文本命令日志 |
| 数据丢失 | 两次快照之间的数据 | 最多 1 秒(everysec) |
| 恢复速度 | 快 | 慢 |
| 文件大小 | 小 | 大 |
| 性能影响 | fork 时短暂卡顿 | 持续的刷盘开销 |
使用建议
- 只做缓存、数据丢了无所谓:可以关闭持久化
- 数据重要且能接受分钟级丢失:只用 RDB,定期把
dump.rdb拷走备份 - 数据要求尽量不丢:开 AOF(
everysec)+ 混合持久化 - 两者都开时,重启优先用 AOF 恢复数据
- 记得给持久化文件所在目录留够磁盘空间,AOF 重写时磁盘不足会导致重写失败
常用命令
# 手动生成 RDB
redis-cli bgsave
# 手动重写 AOF
redis-cli bgrewriteaof
# 查看持久化状态
redis-cli info persistence