Redis ⽀持 RDB 和 AOF 两种持久化机制,Redis 4.0 之后又新增了混合持久化的方式。持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利用之前持久化的⽂件即可实现数据恢复。
1.RDB 持久化
RDB 持久化是把当前进程数据⽣成快照保存到硬盘的过程,触发 RDB 持久化过程分为⼿动触发和⾃动触发。
1.1 触发
⼿动触发分别对应save
和bgsave
命令:
save
命令:阻塞当前Redis
服务器,直到RDB
过程完成为⽌,当内存⽐较⼤的时候可能造成⻓时间阻塞。
bgsave
命令:Redis
进程执⾏fork
操作创建⼦进程,RDB
持久化过程由⼦进程负责,完成后⾃动结束。
fork()
操作在Linux
中是用于创建一个新的进程的系统调用,并且子进程的创建是对父进程的复制。参考了Linux进程 | fork()系统调用详解 - 掘金 (juejin.cn)
自动触发的情况:
- 在配置文件中
redis.conf
,配置save
,如"save m n"
表⽰m
秒内数据集发⽣了n
次修改,⾃动RDB
持久化。
- 执⾏
shutdown
命令关闭Redis
时,执⾏RDB
持久化。
java
shutdown save
1.2 RDB 文件的处理
持久化的数据是默认保存在"/var/lib/redis/"
下,文件名可以通过 dbfilename
指定。
可以通过执⾏config set dir{newDir}
和config set dbfilename{newFilename}
运⾏期间动态执⾏,当下次运⾏时RDB⽂件会保存到新⽬录。
Redis
默认采⽤LZF
算法对⽣成的RDB
⽂件做压缩处理,压缩后的⽂件远远⼩于内存⼤⼩,默认开启,可以通过参数config set rdbcompression{yes|no}
动态修改。
1.3 RDB 优缺点
- 优点:
- 性能高效:RDB持久化是将内存中的数据以二进制形式保存到硬盘上,因此在持久化过程中不需要进行额外的序列化和反序列化操作,具有很高的性能。
- 恢复速度快:因为 RDB 文件是一个完整的数据库快照,所以在 Redis 重启后,可以非常快速地将数据恢复到内存中。
- 缺点:
- 数据可能丢失:RDB持久化是间隔一定时间进行的,如果Redis意外崩溃,会导致最后一次持久化之后的数据丢失。
- 不适合实时备份 :
RDB
⽅式数据没办法做到实时持久化/秒级持久化。因为bgsave
每次运⾏都要执⾏fork
创建⼦进程,属于重量级操作,频繁执⾏成本过⾼。
2.AOF 持久化
AOF
持久化:以独⽴⽇志的⽅式记录每次写命令 ,重启时再重新执⾏AOF
⽂件中的命令达到恢复数据的⽬的。AOF
的主要作⽤是解决了数据持久化的实时性。
2.1 开启 AOF
- 在配置文件中设置,
appendonly yes
,默认是不开启的。
- 流程
- 所有的写⼊命令会追加到缓冲区中。
- AOF 缓冲区根据对应的策略向硬盘做同步操作。
- 随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件进⾏重写,达到压缩的⽬的。
- 当 Redis 服务器启动时,可以加载 AOF ⽂件进⾏数据恢复。
AOF 为什么需要缓冲区?如果每次写 AOF ⽂件都直接同步硬盘,性能从内存的读写变成 IO 读写,必然会下降。先写⼊缓冲区可以有效减少 IO 次数。
2.2 AOF缓冲区同步⽂件策略
可以在配置文件中设置文件同步策略。
- 一共有三种策略
- always:每次写入缓冲区后直接写入 AOF 文件中。
- everysec(默认):写入缓冲区后,不进行同步。一秒后再进行写入 AOF 文件。
- no:只执行 write 操作(也就是只缓存),由操作系统控制写入 AOF 文件的频率。
2.3 重写机制
随着命令不断写⼊ AOF,⽂件会越来越⼤,当达到一定的程度后,Redis 会重写文件,减少文件的体积。
- AOF重写过程可以⼿动触发和⾃动触发:
- 手动:调⽤
bgrewriteaof
命令。 - 自动:在配置文件中
auto-aof-rewrite-min-size
:表⽰触发重写时AOF的最⼩⽂件⼤⼩,默认为64MB。auto-aof-rewrite-percentage
:代表当前AOF占⽤⼤⼩相⽐较上次重写时增加的⽐例。
- 手动:调⽤
- 重写流程
- 父进程执行 fork 创建子进程后。
- 重写
- 主进程 fork 后,继续响应其它命令。所有修改操作写入 AOF 缓冲区,并根据同步策略同步到硬盘,来保证旧 AOF 文件机制的正确。
- ⼦进程只有 fork 之前的所有内存信息,⽗进程中需要将 fork 之后这段时间的修改操作写⼊ AOF 重写缓冲区中。
- ⼦进程根据内存快照,将命令合并到新的 AOF ⽂件中(这里跟 RDB 有点相似)。
- 子进程完成重写
- 新⽂件写⼊后,⼦进程发送信号给⽗进程。
- ⽗进程把 AOF 重写缓冲区内 临时保存的命令追加到新AOF⽂件中。
- ⽤新AOF⽂件替换⽼AOF⽂件。
2.4 AOF 的优缺点
- 优点
- 实时性好:由于 AOF 持久化方式是将每一个写命名记录到文件中,因此实时性比 RDB 更好。
- 可读性高:AOF 文件是一个纯文本文件,可以被人类读取和理解。
- 缺点
- 写入性能略低:由于 AOF 持久化方式需要将每一个写命令记录到文件中,因此相对于 RDB 持久化方式,它的写入性能略低。
- 占用磁盘空间大:由于 AOF 持久化方式需要记录每一个写命令,因此相对于 RDB 持久化方式,它占用的磁盘空间更大。
3.混合模式持久化
在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。
3.1 开启混合持久化
- 在配置文件中如下设置:
4.启动恢复数据的流程
- 判断是否开启 AOF 持久化,开启继续执行后续流程,未开启执行加载 RDB 文件的流程。
- 判断 appendonly.aof 文件是否存在,文件存在则执行后续流程。
- 判断 AOF 文件开头是 RDB 的格式, 先加载 RDB 内容再加载剩余的 AOF 内容。
- 判断 AOF 文件开头不是 RDB 的格式,直接以 AOF 格式加载整个文件。