Redis面试之持久化机制(RDB、AOF)

所谓知其然知其所以然,开篇咱们先考虑一个问题,那就是Redis为什么需要将数据持久化呢,快,先思考一分钟!

好了,大家都知道 redis 将数据存储在内存里,但是不怕一万就怕万一,万一哪天机器咔嚓一下宕机了,那么后果可能很操蛋,数据可能会全部丢失,为了避免这种糟糕的情况就需要持久化机制来保证数据不会因为某些故障而丢失。

下面进入正题


Redis 的持久化机制主要有两种:
一是RDB快照,二是AOF日志

一、RDB快照
这种机制是将内存中数据以快照的方式写入到二进制文件里,默认的文件是 dump.rdb。它是一次全量的备份,也是默认的持久化方式。

1、触发机制(手动触发和自动触发)
(1)手动触发
对应save和bgsave命令:
save命令:同步,会阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存较大的实例会长时间阻塞,线上环境一般禁止使用。流程图如下:

在这里插入图片描述

bgsave 命令:异步, 即 background save,执行这个命令时Redis主进程会 fork 创建一个子进程来负责 RDB 持久化工作,完成后自动结束。因此,阻塞其实只发生在时间很短的 fork 阶段。bgsave是对 save 做的一种优化,Redis 内部基本所有的 RDB 操作都是采用 bgsave。流程如下:
在这里插入图片描述
(2)自动触发
场景一:配置redis.conf
配置 save m n,表示 m秒内数据集存在 n 次修改时,系统将自动触发 bgsave 操作。当设置了多个 save 的配置,只要任意一个满足,都会触发一次 bgsave。比如 save 900 1,表示 900 秒内如果至少有 1 个 key 值变化,则保存。
在这里插入图片描述

场景二:执行 shutdown 命令关闭服务器时,如果没有开启 AOF 持久化,就会自动执行一次 bgsave 操作

 
场景三:主从同步(slave 和 master 建立同步机制)
在这里插入图片描述
2、RDB 的优势和劣势
优点
(1)RDB 文件小,它保存了某个时间点的数据集,适用于数据集的备份,
很方便传送到另一个远端数据中心,非常适用于灾难恢复。
(2)RDB 在保存文件时父进程只需要 fork 一个子进程,接下来所有工作由子进程负责,父进程不阻塞,能最大化 redis 性能。
(3)RDB 文件是一个非常紧凑的二进制文件,相比 AOF 机制,RDB 在恢复大数据集时会更快一些。
缺点
(1)当数据集较大的时,fork 的过程非常耗时。
(2)不可控、丢失数据。RDB 快照在子进程持久化期间,父进程可能会修改内存,此时万一 Redis 意外宕机,可能会丢失数据。

 
二、AOF机制
AOF 机制针对 RDB 的缺点做了优化,这种方式通俗理解就是日志记录,它将每一个写操作都以日志的形式记录下来并追加到文件中(类似 mysql 的 binlog), 这种方式是连续的增量备份。当 Redis 重启时会重新执行文件中保存的命令在内存中重建整个数据集。

1、AOF运行原理(创建和恢复)
创建:
在这里插入图片描述

恢复:
在这里插入图片描述

2、AOF持久化三种策略
always
每次有新命令追加到 AOF 文件时就fsync同步一次:慢但非常安全。
在这里插入图片描述
everysec
每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),且在故障时只会丢失 1 秒的数据。该策略可以兼顾速度和安全性,是默认的策略。
在这里插入图片描述
no
从不 fsync :将数据交给操作系统来处理,由操作系统来决定什么时候同步数据。更快,但是很不安全。
在这里插入图片描述

always、everysec、no对比
在这里插入图片描述

3、AOF重写
既然 AOF 持久化是通过保存被执行的写命令来记录状态的,那么随着时间推移,AOF 文件中的内容会越来越多,体积也会越来越大,可以预见的是,过大的 AOF 文件很可能对 Redis 甚至宿主机器产生影响。为了解决这个问题,就有了 AOF 重写。
在这里插入图片描述

  1. 客户端发出 bgrewriteaof 命令
  2. redis 主进程 fork 子进程
  3. 父进程继续处理 client 请求,除了把写命令写入到旧的 AOF 文件中,同时也将收到的写命令写到 AOF 重写缓冲区。这样能保证重写期间如果有新的写命令进来不会被漏掉,否则会数据不一致
  4. 子进程根据内存快照,按照命令合并规则将命令写入新的 AOF 文件
  5. 当子进程把内存快照写入临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件
  6. 现在父进程可以使用临时文件替换旧的 AOF 文件,后面收到的写命令也开始往新的 AOF 文件中追加

在整个重写过程中,可能有三个地方会阻塞 Redis
fork 子进程阶段,开销与 bgsave 一致。
主进程将重写缓冲区的数据写入到新的 AOF 文件。
用新的 AOF 文件替换来的 AOF 文件。

4、AOF机制的优缺点
优点
(1)可以更好的保护数据不丢失,默认的策略下,最坏情况最多丢失1秒钟的数据。
(2)AOF文件是一个只进行追加的日志文件,没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
(3)AOF文件体积过大时,redis自动在后台对 AOF 进行重写。整个重写操作是绝对安全的,因为在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里,即使重写过程中发生停机,现有AOF 文件也不会丢失。而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
(4)AOF 文件有序保存了对数据库执行的所有写操作,这些操作以 Redis 协议的格式保存,因此 AOF 文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export) AOF 文件也非常简单:举个例子,如果不小心执行了 FLUSHALL 命令,但只要 AOF 文件未被重写,那么只要停止服务器, 移除 AOF文件末尾的 FLUSHALL 命令,并重启 Redis,就可以将数据集恢复到 FLUSHALL 执行之前的状态。

缺点
(1)对于相同的数据集来说,AOF 文件体积通常大于 RDB 文件。恢复大数据集时 AOF 的恢复速度比RDB慢。
(2)根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB。在默认条件下, 每秒 fsync 的性能依然非常高,关闭 fsync 可以让 AOF 的速度和 RDB 一样快。

 
三、RDB 和 AOF 混合模式
通过上面的介绍我们知道:
RDB 能够快速存储和恢复数据,但在服务器宕机时会丢失大量数据,没有保证数据的实时性和安全性
AOF 能够实时持久化数据并且提高了数据的安全性,但是在存储和恢复数据方面又会消耗大量时间

那么问题来了,有没有“鱼和熊掌可兼得”的方案呢?
有!

Redis 4.0 推出了 RDB-AOF 混合持久化方案,该方案是在 AOF 重写阶段创建一个同时包含 RDB 数据和 AOF 数据的 AOF 文件,其中 RDB 数据位于 AOF 文件的开头,他存储了服务器开始执行重写操作时 Redis 服务器的数据状态(RDB 快照),而重写操作执行之后的 Redis 命令,则继续添加在这个 AOF 文件末尾,即 RDB 数据后面(AOF日志追加)。因此,在 Redis 重启时,就可以先加载 RDB 文件,然后再加载 AOF 文件,重启的效率得到提升。而且在运行阶段 Redis 命令都会以日志的形式写入 AOF 文件中,又保证了数据的实时性和安全性。

 
 
 
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值