RDB、AOF、混合持久化(Redis4.0引入)
原理: RDB持久化是将 Redis 在内存中的数据库状态(数据库的键值对等信息)生成快照保存到磁盘里面,生成的 RDB 文件是经过压缩的二进制文件。
触发命令: save
、bgsave
(background save)
save
:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存 比较大的实例会造成长时间阻塞,线上环境不建议使用。bgsave
:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。Redis内部所有的涉 及RDB的操作都采用bgsave的方式,而save命令已经废弃。
自动触发RDB的持久化 机制:
save m n
表示m
秒内数据集存在n
次修改时,自动触发bgsave
。
从节点执行全量复制操作时,主节点自动执行bgsave生成RDB文件并发送给从节点。
默认情况下执行shutdown
命令时,如果没有开启AOF
持久化功能则自动执行bgsave
。
save 900 1 # 900秒内有1个key发生了变化,则触发保存RDB文件
save 300 10 # 300秒内有10个key发生了变化,则触发保存RDB文件
save 60 10000 # 60秒内有10000个key发生了变化,则触发保存RDB文件
Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression{yes|no}
动态修改。
虽然压缩RDB会消耗CPU,但可大幅降低文件的体积,方便保存到硬盘或通过网络发送给从节点,因此线上建议开启。
优点:
缺点:
原理: AOF持久化策略是将发送到Redis服务端的每一条目录都记录下来,并保存到硬盘中的AOF文件。
配置方式:(默认不开启)
AOF 持久化功能的实现可以分为三个步骤: 命令追加、文件写入、文件同步。
命令追加: 当 AOF 持久化功能打开时,服务器在执行完一个写命令之后,会将被执行的写命令追加到服务器状态的 aof 缓冲区(aof_buf
)的末尾。
文件写入与文件同步: 为什么将 aof_buf
的内容写到磁盘上需要两步操作,这边简单解释一下。
Linux 操作系统中为了提升性能,使用了页缓存(page cache)。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些。
aof 缓冲区的内容先写入到 Linux 的页缓存,然后通过 fsync
命令强制同步到磁盘。
AOF文件重写策略:
重写是优化AOF文件,可以使用BGREWRITEAOF
命令来重写AOF文件。
AOF持久化会保存每一条被执行的写命令,那么随着服务器运行时间的增长,对应的AOF文件内容会越来越多,文件也会越来越大,从而对服务器造成影响,为此,Redis提供了文件重写的功能,来解决AOF文件过大问题,它是通过重写程序aof_write实现的。
AOF文件中重写后全部都是Redis主进程中全部数据的写命令。
为什么要重写呢?
lpush list a、lpush list b、lpush list c
可以转化为:lpush list a b c
。AOF重写降低了文件占用空间,除此之外,另一个目的是:更小的AOF文件可以更快地被Redis加载。
为什么要设计两种持久化方式:
因为RDB方式存在的缺陷,如果在没有触发快照的情况下,机器宕机,数据会丢失。
AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。
总结: 作为缓存可以不用持久化,大不了走DB,作为内存数据库一定要持久化了。
RDB是全量的,AOF是实时的。
RDB适合备份,默认开启。
AOF默认不开启,如果AOF开启,Redis启动时会从AOF文件恢复数据,否则从RDB文件恢复数据。
在Redis的实际使用过程中,可以将RDB持久化和AOF持久化同时使用,RDB用于灾难数据恢复(快速的数据恢复),AOF用于服务器重启数据恢复(AOF保证据不丢失)。
Redis重启时加载持久化文件的顺序: 如果同时启用了 AOF 和 RDB,Redis 重新启动时,会使用 AOF 文件来重建数据集,因为通常来说, AOF 的数据会更完整。
流程说明:
DB loaded from append only file: 5.841 seconds
DB loaded from disk: 5.586 seconds
描述: 混合持久化并不是一种全新的持久化方式,而是对已有方式的优化。混合持久化只发生于 AOF 重写过程。使用了混合持久化,重写后的新 AOF 文件前半段是 RDB 格式的全量数据,后半段是 AOF 格式的增量数据。
整体格式为: [RDB file][AOF tail]
开启: 混合持久化的配置参数为 aof-use-rdb-preamble
,配置为 yes
时开启混合持久化,在 Redis4 刚引入时,默认是关闭混合持久化的,但是在 Redis5 中默认已经打开了。
关闭: 使用 aof-use-rdb-preamble no
配置即可关闭混合持久化。
混合持久化本质是通过 AOF 后台重写(bgrewriteaof
命令)完成的,不同的是当开启混合持久化时,fork
出的子进程先将当前全量数据以 RDB
方式写入新的 AOF
文件,然后再将 AOF
重写缓冲区(aof_rewrite_buf_blocks
)的增量命令以 AOF
方式写入到文件,写入完成后通知主进程将新的含有 RDB
格式和 AOF
格式的 AOF
文件替换旧的的 AOF
文件。
优点: 结合 RDB 和 AOF 的优点, 更快的重写和恢复。
缺点: AOF 文件里面的 RDB 部分不再是 AOF 格式,可读性差。
如果想尽量保证数据安全性, 你应该同时使用 RDB 和 AOF 持久化功能,同时可以开启混合持久化。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
如果你的数据是可以丢失的,则可以关闭持久化功能,在这种情况下,Redis 的性能是最高的。