四、Redis数据快速恢复之RDB(Redis DataBase)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四、Redis数据快速恢复之RDB(Redis DataBase)相关的知识,希望对你有一定的参考价值。

参考技术A

内存快照(将内存中的数据在某一时刻的状态记录至磁盘中) 。现实可以理解为拍照。

想象下如果100个人(数据)在拍照,那首先想到的问题这100个人给谁拍照?拍照的同时如果有人"动"了怎么办?基于这些场景繁衍以下问题:

全量快照 ,一次性记录所有数据,保证数据的完整性

Redis 两个命令生成 RDB 文件, save 和 bgsave。
save:在主线程中执行,导致阻塞;
bgsave:创建一个子进程,用于写入 RDB 文件,避免主线程阻塞。(Redis默认配置项使用bgsave)。

采用bgsave因为Redis会fock一个子进程处理,所以读肯定没问题,修改是怎么处理的呢?
Redis借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。具体流程:

主线程 fork 出 bgsave 子进程后,bgsave 子进程实际是复制了主线程的页表。这些页表中,就保存了在执行 bgsave 命令时,主线程的所有数据块在内存中的物理地址。这样一来,bgsave 子进程生成 RDB 时,就可以根据页表读取这些数据,再写入磁盘中。如果此时,主线程接收到了新写或修改操作,那么,主线程会使用写时复制机制。具体来说,写时复制就是指,主线程在有写操作时,才会把这个新写或修改后的数据写入到一个新的物理地址中,并修改自己的页表映射。

如图:

bgsave 子进程复制主线程的页表以后,假如主线程需要修改虚页 7 里的数据,那么,主线程就需要新分配一个物理页(假设是物理页 53),然后把修改后的虚页 7 里的数据写到物理页 53 上,而虚页 7 里原来的数据仍然保存在物理页 33 上。这个时候,虚页 7 到物理页 33 的映射关系,仍然保留在 bgsave 子进程中。所以,bgsave 子进程可以无误地把虚页 7 的原始数据写入 RDB 文件。

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

快照的恢复速度快,频率无法把控,频率太低,宕机,丢失数据比较多。频率太高,产生额外开销。

混合使用 AOF 日志和内存快照 ,内存快照以一定的频率执行,在两次快照之间, 使用 AOF 日志记录 这期间的所有命令操作。

以上是关于四、Redis数据快速恢复之RDB(Redis DataBase)的主要内容,如果未能解决你的问题,请参考以下文章

Redis之数据备份与恢复

redis 持久化之 RDB & AOF

redis数据同步之redis-shake

redis持久化之rdb

Redis 持久化与故障恢复之rdb

Redis 持久化之RDB和AOF