大聪明教你学Java | 带你了解 Redis 中 RDB 与 AOF 的区别

214 阅读7分钟

前言

“我正在参加「掘金·启航计划」”

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。

🍊支持作者: 点赞👍、关注💖、留言💌~

大聪明前两天刚写了一篇博客,同事看完博客后说:“写的不错,你在博客里提到了 Binlog 的三种模式,那你知道 Redis 里也有类似的东西嘛?” 大聪明听完同事的话以后突然愣住了😳 没错!大聪明果然还是不知道😂... 不过这再一次激起了大聪明的求知欲,我们今天就一起看看大聪明的求知之路💨

传送门:《大聪明教你学Java | 带你了解 Binlog 实现 MySQL 主从同步的原理及实现方式

Redis 中的 RDB 与 AOF

其实大聪明的同事说的就是 Redis 中的 RDB 与 AOF,他们类似于 Binlog 中的 statement 模式和 row 模式。我们都知道,Redis 运行时是将数据保存在内存中的,如果服务器宕机或者重启,那么内存中的数据必然会丢失,从而影响正常的业务运行。所以,我们就必须要把数据持久化到磁盘,以便服务器故障时进行数据恢复。Redis 在持久化时,给我们提供了两种方式,这两种方式就是 RDB 与 AOF。

RDB

RDB 即 RedisDB 的缩写,这种持久化方式是将整个 Redis 内存数据持久化到一个 .rdb 文件中。它保存了 Redis 在某个时间点上的数据集,这种数据集文件非常适用于备份, 比如说,你可以每小时备份出一个 .rdb 文件,并且在每天的24点也备份出一个 .rdb 文件。 这样即使遇上问题,也可以随时将数据集还原到不同的版本。这时候可能就有小伙伴要提出疑问了:“如果 Redis 在做持久化的同时,内存数据被修改了怎么办呢?比如数据一开始是 A,但是在做持久化的时候由 A 变成了 B,那最终持久化到 .rdb 文件中的值是多少呢?😕” 这个问题问的就很好了,我们一起来揭秘一下👇

🧐大家一起来揭秘🧐

在揭秘之前,我们需要先提一个小的知识点,不知道 Linux 下的 fork 函数大家有没有用过呢?fork 函数是 Linux 的子进程创建函数。它会通过复制主进程的方式快速创建一个子进程,并且在 调用 fork 函数时,子进程和主进程有相同的数据内容,二者运行在各自的内存空间,互不影响。Redis 就是通过调用 fork 的方式来创建子进程,并通过子进程进行数据的持久化,所以子进程就会保留持久化开始时刻的数据状况。所以,对于上面那个问题来说,持久化的数据依然是 A。

关于 RDB,Redis 又提供了2种使用方式,分别是命令和配置文件。如果我们选择使用命令的话,就可以通过 save 和 bgsave 命令,触发持久化操作;当然我们也可以选择使用配置文件的方式来进行持久化,比如可以修改 Redis 的配置文件为 save 100 10 (100 秒内有10个key被修改时触发持久化)、 save 60 10000(60 秒内有10000个key被修改时触发持久化)等等。

通过上面的了解,我们也可以总结出 RDB 的一些优缺点了👇

🍌优点🍌

🍋 ① RDB 非常适用于灾难恢复。它只有一个文件,并且内容都非常紧凑,在数据恢复时会比较容易操作。
🍋 ② RDB 可以最大化 Redis 的性能。父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。

🍌缺点🍌

🥝 ① 如果你需要尽量避免在服务器故障时丢失数据,那么我们就最好不要选择 RDB 了。虽然 Redis 允许你设置不同的保存点来控制保存 RDB 文件的频率,但是 RDB 文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此可能会至少花费 5 分钟甚至更多时间才能保存好一次 RDB 文件。那么在这种情况下,一旦发生故障停机,就可能会丢失好几分钟的数据。
🥝 ② 每次保存 RDB 文件的时候,Redis 都要 fork 出一个子进程,并由子进程来进行实际的持久化工作。 那么如果在数据集比较庞大时, fork 操作可能会非常耗时,并可能会造成服务器在若干毫秒内停止处理客户端的请求;如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会更长。

AOF

我们了解完 RDB 后再一起来看看 AOF。它就类似于 Binlog 的 statement 模式,AOF 会将 Redis 中每一步对数据修改的操作记录都记录到相应的文件中。同时为了降低 I/O 消耗,AOF 写文件时,会先将数据写到缓冲区,然后再把缓冲区的内容写到磁盘,这个过程叫做 fsync。我们也可以设置不同的 fsync 策略👇

appendfsync always :每次写操作都会将内容写到磁盘,但是会影响性能 appendfsync everysec :每秒写一次(AOF 的默认策略) appendfsync no :消极等待OS刷新(一般30s),但是可能丢失数据

随着服务器运行时间越来越长,AOF 文件也势必会越来越大,Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写。 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。

通过上面的了解,我们也可以总结出 AOF 的一些优缺点了👇

🍋优点🍋

🍋 ① 不易丢失数据,数据完整性好。我们可以设置fsync策略,一般默认是 everysec,也可以设置每次写入追加,所以即使服务宕机了,也最多丢失一秒的数据。

🍋缺点🍋

🥝 ① 性能相对较差:它的操作模式决定了它会对 Redis 的性能有所损耗。
🥝 ② 由于 AOF 文件较大,所以就导致数据恢复会更慢一些。

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●'◡'●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西