Redis持久化-RDB机制实现原理

概览

上一篇文章主要讲述了AOF持久化机制的实现原理,我们知道AOF日志在保证性能的同时,也能最大程度保证日志的完整性,即使出现服务器宕机等异常情况,也最多只会丢失1s的日志数据。

但因为其记录的是原始的写入指令,因此需要通过指令重放的方式恢复数据,在数据量非常大的情况下,会导致整体恢复耗时较长。

而Redis同时提供了另外一种基于内存快照的持久化技术,可以将数据库某一时刻的状态记录下来存入日志,后续数据恢复时只需要将日志中的数据载入内存即可,因此数据恢复效率更高。

这一持久化技术就是指Redis的RDB持久化机制,本文主要讲述RDB的实现原理。

实现原理

RDB持久化时,会将该时刻的数据库快照写入日志,涉及数据库的全量数据。

如果涉及的数据量较大,那么这个操作是比较耗时的。因此持久化操作是否会阻塞主线程,影响Redis性能,这一点至关重要。

Redis提供了两个指令显示触发RDB持久化操作:

  • SAVE:在主线程中执行,会导致主线程阻塞
  • BGSAVE:创建一个子进程,专门用于RDB持久化操作,避免了主线程阻塞,这也是Redis的默认配置

BGSAVE 子进程在进行快照期间,允许数据发生修改,其同样也是通过写时复制技术实现的:

从图示的例子中可以看到,在 RDB 进行快照的过程中,Key-3发生了修改,此时会额外为 Key-3开辟一块内存空间,在新开辟的空间上进行修改操作,而不影响RDB快照所依赖的旧数据。

除了可以显示触发RDB持久化,Redis还提供自动触发机制,在 redis.conf 可以进行配置:

需要注意的是:

  • 同一时间,只能有一个BGSAVE子进程执行
  • BGREWRITEAOF和BGSAVE两个指令不能同时执行

这么做的原因主要是BGSAVE,BGREWRITEAOF指令都比较占用系统资源,会产生大量的磁盘写入操作,如果允许同时执行则可能影响服务器整体性能。

混合持久化

通过上述内容,我们了解到AOF与RDB两种持久化机制各有优缺点:

  • AOF日志可以保证日志完整性,但数据恢复效率较差
  • RDB日志数据恢复效率很高,但日志完整性较差

因此在Redis 4.0之后,推出了混合持久化机制,通过 redis.conf 可以配置是否开启:

aof-use-rdb-preamble yes

开启混合持久化之后,在AOF重写时,会先以RBD持久化的方式将快照数据记录在日志开头;重写完成后,再将重写期间发生的写指令以AOF格式追加到日志结尾。

重写之后的AOF日志格式如下:

Redis 在启动时会优先根据 AOF 文件进行数据恢复,流程如下:

因此,混合持久化机制结合了RDB和AOF的优点,既能够保证日志的完整性,且数据恢复效率也高,在Redis 5.0是默认开启的。


版权声明:本文为qq_34679704原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。