05 | 内存快照:宕机后,Redis如何实现快速恢复?


Redis核心技术与实战

基础篇

05 | 内存快照:宕机后,Redis如何实现快速恢复?

AOF 方法的好处是每次执行只需要记录操作命令,需要持久化的数据量不大。一般而言,只要采用的不是 always 的持久化策略,就不会对性能造成太大影响。

用 AOF 方法进行故障恢复,需要逐一把操作日志都执行一遍。如果操作日志非常多,Redis 就会恢复得很缓慢,影响到正常使用。

内存快照

所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。

对 Redis 来说,它实现类似照片记录效果的方式,就是把某一时刻的状态以文件的形式写到磁盘上,也就是快照。这样一来,即使宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。这个快照文件就称为 RDB 文件,其中,RDB 就是 Redis DataBase 的缩写。

和 AOF 相比,RDB 记录的是某一时刻的数据,并不是操作,所以在做数据恢复时,可以直接把 RDB 文件读入内存,很快地完成恢复。

给哪些内存数据做快照?

Redis 的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中。

Redis 提供了两个命令来生成 RDB 文件,分别是 savebgsave

  • save:在主线程中执行,会导致阻塞;
  • bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。
快照时数据能修改吗?

做快照时不希望数据“动”,也就是不能被修改。而如果快照执行期间数据不能被修改,无疑会给业务服务造成巨大的影响。

Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据,bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。

如果主线程对这些数据是读操作(例如下图中的键值对 A),那么主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据(例如下图中的键值对 C),那么这块数据就会被复制一份,生成该数据的副本(键值对 C’)。然后,主线程在这个数据副本上进行修改。同时,bgsave 子进程可以继续把原来的数据(键值对 C)写入 RDB 文件。

在这里插入图片描述

可以每秒做一次快照吗?

如下图所示,先在 T0 时刻做了一次快照,然后又在 T0+t 时刻做了一次快照。在这期间,数据块 5 和 9 被修改。如果在 t 这段时间内机器宕机,那么只能按照 T0 时刻的快照进行恢复。此时,数据块 5 和 9 的修改值因为没有快照记录,而无法恢复。

在这里插入图片描述

要想尽可能恢复数据,t 值就要尽可能小,t 越小,就越像“连拍”。但是,如果频繁地执行全量快照,也会带来两方面的开销。

  • 一方面,频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
  • 另一方面,bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁 fork 出 bgsave 子进程,这就会频繁阻塞主线程了。所以,在 Redis 中如果有一个 bgsave 在运行,就不会再启动第二个 bgsave 子进程

增量快照是指做了一次全量快照后,后续的快照只对修改的数据进行快照记录。做增量快照,可以避免每次全量快照的开销。

在第一次做完全量快照后,T1 和 T2 时刻如果再做快照,只需要将被修改的数据(修改后)写入快照文件。但这么做的前提是记住哪些数据被修改,这就需要使用额外的元数据信息去记录哪些数据被修改,会带来额外的空间开销问题。

在这里插入图片描述

为了“记住”修改,引入的额外空间开销比较大。这对于内存资源宝贵的 Redis 来说,有些得不偿失。

虽然跟 AOF 相比,快照的恢复速度快,但是快照的频率不好把握。如果频率太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,采用增量快照的方式,又会产生额外开销。

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。

快照不用很频繁地执行,这就避免了频繁 fork 对主线程的影响。而且,AOF 日志也只用记录两次快照间的操作,因此不会出现文件过大的情况,也可以避免重写开销。

如下图所示,T1 和 T2 时刻的修改,用 AOF 日志记录,等到第二次做全量快照时,就可以清空 AOF 日志。因为此时的修改都已经记录到快照中,所以恢复时就不再用 AOF 日志了。

在这里插入图片描述

这个方法既能拥有 RDB 文件快速恢复的好处,又拥有 AOF 只记录操作命令的简单优势。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久违の欢喜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值