Redis持久化机制!
Redis持久化机制!
月伴飞鱼RDB持久化
将内存中的数据生成快照保存到磁盘里面,保存的文件后缀是
.rdb
。rdb 文件是一个经过压缩的二进制文件,当 Redis 重新启动时,可以读取 rdb 快照文件恢复数据。
- 包括:rdbSave 和 rdbLoad 两个函数。
- rdbSave用于生成 RDB 文件并保存到磁盘,rdbLoad用于将 RDB 文件中的数据重新载入到内存中。
RDB 文件是一个单文件的全量数据,很适合数据的容灾备份与恢复。
- 通过 RDB 文件恢复数据库耗时较短,通常 1G 的快照文件载入内存只需 20s 左右。
RDB文件的生成方式
手动触发保存:
通过 SAVE 和 BGSAVE 命令手动触发快照生成。
SAVE 是一个同步式的命令,它会阻塞 Redis 服务器进程,直到 RDB 文件创建完成为止。
- 在服务器进程阻塞期间,服务器不能处理任何其他命令请求。
BGSAVE 是一个异步式的命令:
- 会派生出一个子进程,由子进程负责创建 RDB 文件,服务器进程(父进程)继续处理客户的命令。
基本过程:
客户端发起 BGSAVE 命令,Redis 主进程判断当前是否存在正在执行备份的子进程,如果存在则直接返回。
父进程 fork 一个子进程 (fork 的过程中会造成阻塞的情况)。
fork 创建的子进程开始根据父进程的内存数据生成临时的快照文件,然后替换原文件。
子进程备份完毕后向父进程发送完成信息。
自动触发保存:
通过 save 选项设置多个保存条件,只要其中任意一个条件被满足,服务器就会执行 BGSAVE 命令。
只要满足以下 3 个条件中的任意一个,BGSAVE 命令就会被自动执行:
- 服务器在 900 秒之内,对数据库进行了至少 1 次修改。
- 服务器在 300 秒之内,对数据库进行了至少 10 次修改。
- 服务器在 60 秒之内,对数据库进行了至少 10000 次修改。
AOF持久化
AOF 会把 Redis 服务器每次执行的写命令记录到一个日志文件中,当服务器重启时再次执行 AOF 文件中的命令来恢复数据。
如果 Redis 服务器开启了 AOF 持久化,会优先使用 AOF 文件来还原数据库状态。
只有在 AOF 的持久化功能处于关闭状态时,服务器才会使用 RDB 文件还原数据库状态。
执行流程
AOF 不需要设置任何触发条件,对 Redis 服务器的所有写命令都会自动记录到 AOF 文件中。
AOF 文件的写入流程可以分为 3 个步骤:
命令追加(append):将 Redis 执行的写命令追加到 AOF 的缓冲区
aof_buf
。文件写入(write)和文件同步(fsync):AOF 根据对应的策略将
aof_buf
的数据同步到硬盘。文件重写(rewrite):定期对 AOF 进行重写,从而实现对写命令的压缩。
AOF缓冲区的文件同步策略
appendfsync always:每执行一次命令保存一次
- 命令写入
aof_buf
缓冲区后立即调用系统 fsync 函数同步到 AOF 文件,fsync 操作完成后线程返回,整个过程是阻塞的。appendfsync no:不保存
- 命令写入
aof_buf
缓冲区后调用系统 write 操作,不对 AOF 文件做 fsync 同步。
- 同步由操作系统负责,通常同步周期为 30 秒。
appendfsync everysec:每秒钟保存一次
- 命令写入
aof_buf
缓冲区后调用系统 write 操作,write 完成后线程立刻返回,fsync 同步文件操作由单独的进程每秒调用一次。
文件同步策略 | write 阻塞 | fsync 阻塞 | 宕机时的数据丢失量 |
---|---|---|---|
always | 阻塞 | 阻塞 | 最多只丢失一个命令的数据 |
no | 阻塞 | 不阻塞 | 操作系统最后一次对 AOF 文件 fsync 后的数据 |
everysec | 阻塞 | 不阻塞 | 一般不超过 1 秒钟的数据 |
文件重写
把对 AOF 文件中的写命令进行合并,压缩文件体积,同步到新的 AOF 文件中,然后使用新的 AOF 文件覆盖旧的 AOF 文件。
触发机制:
手动触发:
- 调用 bgrewriteaof 命令,执行与 bgsave 有些类似
自动触发:
- 根据
auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
配置项,以及aof_current_size
和aof_base_size
的状态确定触发时机
- auto-aof-rewrite-min-size:执行 AOF 重写时,文件的最小体积,默认值为 64MB
- auto-aof-rewrite-percentage:
- 执行 AOF 重写时,当前 AOF 大小(
aof_current_size
)和上一次重写时 AOF 大小(aof_base_size
)的比值
重写流程:
客户端通过
bgrewriteaof
命令对 Redis 主进程发起 AOF 重写请求。主进程通过 fork 操作创建子进程,这个过程主进程是阻塞的。
主进程的 fork 操作完成后,继续处理其他命令,把新的写命令同时追加到
aof_buf
和aof_rewrite_buf
缓冲区中。
- 在文件重写完成之前,主进程会继续把写命令追加到
aof_buf
缓冲区,这样可以避免 AOF 重写失败造成数据丢失,保证原有的 AOF 文件的正确性。- 由于 fork 操作运用写时复制技术,子进程只能共享 fork 操作时的内存数据,主进程会把新命令追加到一个
aof_rewrite_buf
缓冲区中,避免 AOF 重写时丢失这部分数据。子进程读取 Redis 进程中的数据快照,生成写入命令并按照命令合并规则批量写入到新的 AOF 文件。
子进程写完新的 AOF 文件后,向主进程发信号。
主进程接受到子进程的信号以后,将
aof_rewrite_buf
缓冲区中的写命令追加到新的 AOF 文件。主进程使用新的 AOF 文件替换旧的 AOF 文件,AOF 重写过程完成。
RDB的优缺点:
优点:
- RDB 是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集,适合做数据的备份、灾难恢复。
- 与 AOF 持久化方式相比,恢复大数据集的时候会更快。
缺点:
数据安全性是不如 AOF,保存整个数据集是个重量级的过程,可能要几分钟才进行一次持久化。
如果服务器宕机,就可能丢失几分钟的数据。
Redis 数据集较大时,fork 的子进程要完成快照会比较耗费 CPU 和时间。
AOF的优缺点
优点:
- 数据更完整,安全性更高,秒级数据丢失。
- AOF 文件是一个只进行追加的命令文件,且写入操作是以 Redis 协议的格式保存的,内容是可读的,适合误删紧急恢复。
缺点:
对于相同的数据集,AOF 文件的体积要远远大于 RDB 文件,数据恢复也会比较慢。
RDB-AOF混合持久化
Redis 4.0 版本提供了一套基于 AOF-RDB 的混合持久化机制,保留了两种持久化机制的优点。
这样重写的 AOF 文件由两部份组成,一部分是 RDB 格式的头部数据,另一部分是 AOF 格式的尾部指令。
在 Redis 服务器重启的时候:
- 可以预先加载 AOF 文件头部全量的 RDB 数据。
- 然后再重放 AOF 文件尾部增量的 AOF 命令,从而大大减少了重启过程中数据还原的时间。