RDB: alt

1、全量快照

Redis提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave。

1、save:在主线程中执行,会导致阻塞;

2、bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。

为了保证在全量快照时,能够正确处理写请求,RDB采用的COW(copy-on-write)机制:当bgsave在fork之后,对于读请求,主线程和bgsave子线程都是共享内存的,如上图中的键值对A;但是,在主线程处理写请求时,会触发COW机制,将拟修改的内存拷贝一份,比如图中的键值对C,将会copy出一份副本:键值对C‘,此时主线程可以直接对C'进行修改,而bgsave子线程依然可以保存键值对C。

2、增量快照

alt 因为频繁的全量快照,会带来两方面的性能损失:

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

所以,我们可以采用增量快照的方式,只用记录两次全量快照期间,哪些数据被修改了,它需要我们使用额外的元数据信息去记录哪些数据被修改了,这会带来额外的空间开销问题,如上图所示。为了“记住”修改,引入的额外空间开销比较大。这对于内存资源宝贵的 Redis 来说,有些得不偿失。同时,快照的频率不好把握,如果频率太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,又会产生额外开销。为了弥补增量全照在这方面的缺陷,所以有了混合使用AOF日志和RDB快照的方式。

3、混合使用 AOF 日志和内存快照(Redis 4.0 提出:设置的参数是: aof-use-rdb-preamble yes)

简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有 命令操作。AOF就不用记录所有操作了,只需要记录增量记录即可,记录量就小了。若要恢复数据,可用RDB文件再加上AOF日志就可以全量恢复数据了。在速度上,因为RDB是二进制数据流,可以快速恢复出redis数据,然后在此基础上小量的执行AOF操作命令,相比于只用AOF来恢复全量数据的操作,也不会太多影响到恢复速度。

alt

如上图所示,当等到下一次全量快照时,可以将AOF文件清空,因为此时修改的数据已经同步到快照中了,恢复时就不需要再用AOF日志了。