目录
- 一、RDB
-
- [1.1 触发机制](#1.1 触发机制)
- [1.2 文件处理](#1.2 文件处理)
- [1.3 优缺点](#1.3 优缺点)
- 二、AOF
-
- [2.1 使用方式](#2.1 使用方式)
- [2.2 缓冲区⽂件同步策略](#2.2 缓冲区⽂件同步策略)
- [2.3 重写机制](#2.3 重写机制)
-
- [2.3.1 触发机制](#2.3.1 触发机制)
- [2.3.2 重写流程](#2.3.2 重写流程)

要想数据持久化,我们就需要把数据保存在硬盘中,又因为Redis要保持查询高效,所以Redis将数据在内存和硬盘中都存储了一份。
Redis ⽀持 RDB(Redis Database) 和 AOF(Append Only File) 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。
一、RDB
RDB 定期 将 Redis 内存中的所有数据,写入硬盘,生成 一个"快照"。
- 快照的意思就是,当内存数据没了的时候,我们存在硬盘里面的就可以重新存入内存,硬盘数据就相当于一个照片
- 定期:有两种方式,手动触发和自动触发。
2.1. 手动触发:通过客户端执行特定命令如 save / bgsave ,来触发快照
2.2. 自动触发:在Redis 配置文件中,设置让Redis 隔多长时间,多少次修改 触发快照。
1.1 触发机制
手动触发:
- save : 执行save 命令的时候,会阻塞当前的Redis服务器,直到 RDB 过程完成为⽌,可能造成Redis挂等不可预料的后果,不使用。
- bgsave:
2.1. Redis ⽗进程判断当前进是否存在其他正在执⾏的⼦进程,如 RDB/AOF ⼦进程,如果存在 bgsave 命令直接返回。
2.2. ⽗进程执⾏ fork 创建⼦进程,fork 过程中⽗进程会阻塞,通过 info stats 命令查看 latest_fork_usec 选项,可以获取最近⼀次 fork 操作的耗时,单位为微秒。
2.3. ⽗进程 fork 完成后,bgsave 命令返回 "Background saving started" 信息并不再阻塞⽗进程,可以继续响应其他命令。
2.4. ⼦进程创建 RDB ⽂件,根据⽗进程内存⽣成临时快照⽂件,完成后对原有⽂件进⾏原⼦替换。执⾏ lastsave 命令可以获取最后⼀次⽣成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选项。
2.5. 进程发送信号给⽗进程表⽰完成,⽗进程更新统计信息。
bgsave 执行流程图
1.2 文件处理
保存:RDB ⽂件保存进 dir 配置指定的⽬录(默认/var/lib/redis/)下,⽂件名通过 dbfilename 配置(默认 dump.rdb)指定。可以通过执⾏ config set dir {newDir} 和 config set dbfilename {newFilename} 运⾏期间动态执⾏,当下次运⾏时RDB ⽂件会保存到新⽬录。
压缩:Redis 默认采⽤ LZF 算法对⽣成的 RDB ⽂件做压缩处理,压缩后的⽂件远远⼩于内存⼤⼩,默认开启,可以通过参数 config set rdbcompression {yes|no} 动态修改。
校验:如果 Redis 启动时加载到损坏的 RDB ⽂件会拒绝启动。这时可以使⽤ Redis 提供的 redischeck-dump⼯具检测 RDB ⽂件并获取对应的错误报告。
RDB文件替换,当进行RDB镜像操作的时候,会先将快照数据保存在临时文件中,快照数据生成完毕,将原来RDB文件删除,使用临时文件作为新的RDB文件。
1.3 优缺点
- RDB 是⼀个紧凑压缩的⼆进制⽂件,代表 Redis 在某个时间点上的数据快照。⾮常适⽤于备份,全量复制等场景。
- Redis 加载 RDB 恢复数据远远快于 AOF 的⽅式。
- RDB ⽅式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运⾏都要执⾏ fork 创建⼦进程,属于重量级操作,频繁执⾏成本过⾼。
- RDB ⽂件使⽤特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有⻛险。
二、AOF
AOF(Append Only File)持久化:以独⽴⽇志的⽅式记录每次写命令,重启时再重新执⾏ AOF ⽂件中的命令达到恢复数据的⽬的。AOF 的主要作⽤是解决了数据持久化的实时性。
2.1 使用方式
开启 AOF 功能需要设置配置:appendonly yes,默认不开启。AOF ⽂件名通过 appendfilename 配置(默认是 appendonly.aof)设置。保存⽬录(/var/lib/redis/)通过 dir 配置指定。
AOF 的⼯作流程操作:命令写⼊(append)、⽂件同步(sync)、⽂件重写(rewrite)、重启加载(load)

AOF 机制每次都先将命令写入 aof_buf(缓冲区)中,达到一定数量,在统一顺序写入硬盘中。因为这样的机制导致对Redis的速度几乎是没啥影响的。
2.2 缓冲区⽂件同步策略
Redis 提供了多种 AOF 缓冲区同步⽂件策略,由参数 appendfsync 控制(/var/lib/redis/)。
| 可配置值 | 说明 |
|---|---|
| always | 命令写⼊ aof_buf 后调⽤ fsync 同步,完成后返回 |
| everysec | 命令写⼊aof_buf 后只执⾏ write 操作,不进⾏ fsync。每秒由同步线程进⾏ fsync。 |
| no | 命令写⼊ aof_buf 后只执⾏ write 操作,由 OS 控制 fsync 频率。 |
write:写入系统缓冲区即返回,数据同步依赖系统调度,宕机可能丢失。
fsync:强制刷盘,阻塞直到数据落盘,最安全。
AOF 同步策略:
- always:每条命令落盘,安全但性能极差。
- no:性能高,数据丢失风险大。
- everysec(默认推荐):每秒刷盘一次,兼顾安全与性能,最多丢1秒数据。
2.3 重写机制
随着命令不断写⼊ AOF,⽂件会越来越⼤,为了解决这个问题。Redis 引⼊ AOF 重写机制压缩⽂件体积。
重写就是,针对AOF文件进行整理,提出文件中的冗余操作,合并一些可合并的操作,减小AOF文件体积。(本质上当前Redis内存中的数据,就是所有命令都执行后的结果了)。
2.3.1 触发机制
- ⼿动触发:调⽤ bgrewriteaof 命令。
- ⾃动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时机。
2.1. auto-aof-rewrite-min-size:表⽰触发重写时 AOF 的最⼩⽂件⼤⼩,默认为 64MB。
2.2. auto-aof-rewrite-percentage:代表当前 AOF 占⽤⼤⼩相⽐较上次重写时增加的⽐例。
2.3.2 重写流程
- 执⾏ AOF 重写请求
如果当前进程正在执⾏ AOF 重写,请求不执⾏。如果当前进程正在执⾏ bgsave 操作,重写命令延迟到 bgsave 完成之后再执⾏。 - ⽗进程执⾏ fork 创建⼦进程。
- 重写
3.1. 主进程 fork 之后,继续响应其他命令。所有修改操作写⼊ AOF 缓冲区并根据 appendfsync 策略同步到硬盘,保证旧 AOF ⽂件机制正确。
3.2. ⼦进程只有 fork 之前的所有内存信息,⽗进程中需要将 fork 之后这段时间的修改操作写⼊ AOF 重写缓冲区中。 - ⼦进程根据内存快照,将命令合并到新的 AOF ⽂件中。
- ⼦进程完成重写
5.1. 新⽂件写⼊后,⼦进程发送信号给⽗进程。
5.2. ⽗进程把 AOF重写缓冲区内临时保存的命令追加到新 AOF ⽂件中。
5.3. ⽤新 AOF ⽂件替换⽼ AOF ⽂件。

