Redis持久化

Table of contents

  1. 1. Redis持久化
    1. 1.1. Redis持久化方式
      1. 1.1.1. RDB还是AOF?
    2. 1.2. RDB详解
      1. 1.2.1. 写时复制
    3. 1.3. AOF详解
      1. 1.3.1. AOF写入流程
      2. 1.3.2. AOF重写
      3. 1.3.3. AOF混合持久化

Redis持久化

持久化是什么?

Redis中的数据是存储在内存上的,倘若发生系统奔溃或程序重启,Redis中的数据就会丢失。如果业务场景希望即使出现异常情况,Redis中的数据也不会丢失,就需要将Redis中的数据持久化保存到存储设备上。

Redis持久化方式

Redis提供了两种持久化方式:

  1. RDB(Redis Database Backup)是一种保存数据快照的持久化策略。当开启RDB策略后,Redis每个一段时间就会将全局数据以二进制数据的形式保存在磁盘,后续通过加载RDB文件恢复数据。

    image-20241025140840529
  2. AOF(Append Only File)以记录日志确保数据持久化。当开启AOF策略后,Redis会将每一条数据更新操作记录到日志,后续通过重放日志恢复数据

    image-20241025140840529

从两种策略的定义中很容易能看出来两种方案有一下不同点:

  • 体积:在同等数据量的情况下,RDB比AOF体积更小,因为RDB保存的是二进制紧凑数据
  • 恢复速度:RDB是快照数据,直接加载即可恢复数据,而AOF文件恢复需要重放日志,开销更大
  • 数据完整性:RDB是间隔一段时间就记录一次,相比之下,AOF文件记录每一条操作,保存的数据更加完整

RDB还是AOF?

在Redis中,RDB是默认开启的,而AOF是默认关闭的。

使用RDB还是AOF持久化策略需要依据具体场景判断:

如果对数据完整性要求较高,则需要将RDB、AOF同时开启。此时,进行数据恢复只会采用AOF文件,因为既然开启了AOF策略那么就说明需要数据完整性更强的AOF文件,而不是可能缺少一些数据的RDB文件

image-20241025143254030

如果能够忍受几分钟的数据丢失,就可以只开启RDB策略。但不建议单独开启AOF策略,具体原因可参考官方的解释:

image-20241025143518646

RDB详解

RDB属于数据快照持久化策略,是一种最常见、最稳定的数据持久化方案。那么如何在Redis中开启RDB持久化策略?

由于Redis默认支持RDB持久化,因此我们可以在配置文件中看到如下内容

image-20241025194036067

其中save interval changes就代表着当一定时间间隔进行了多少次数据修改就触发RDB持久化,将数据保存到磁盘上

当然,除了上述被动触发RDB持久化,Redis还提供了两条命令来支持主动持久化功能

  • save:Redis主线程将全局数据生成二进制文件。如果内存中的数据量庞大,那么该命令可能会导致主线程阻塞,降低系统的执行效率
  • bgsave:Redis主线程fork一个子进程,子进程执行持久化数据的操作生成一个新的rdb文件并将旧的rdb文件替换,避免了主线程阻塞
    • 上述被动触发RDB持久化本质上就是调用了bgsave命令

除此之外,Redis在程序关闭时会自动触发save命令,阻塞主线程进行数据持久化,以记录更加完全的数据。

写时复制

调用bgsave命令后,执行RDB持久化过程中,Redis依然可以继续处理其他命令,这都得益于写时复制技术

Redis主线程fork子进程时,为了节省内存空间,子进程仅仅复制父进程的页表,两个进程的页表指向同一块物理内存。

image-20241025202223000

接着,子进程依据物理内存上的数据生成新的rdb文件。因为RDB是快照持久化策略,子进程只会保存调用bgsave命令那一刻的数据,所以即使生成rdb文件的过程中主进程发生了写操作,也不能影响子进程的数据。为了满足这一要求,主进程会复制一份对应的物理内存,然后在上面进行写操作,从而不影响子进程的数据,这就是写时复制机制。

image-20241025202241119

AOF详解

AOF持久化策略在Redis中是默认关闭的,需要手动开启,开启之后,Redis会将每一条更新操作记录在AOF文件。当重启时,Redis就可以通过AOF文件将所有的请求重放,恢复数据,但速度很慢。

AOF写入流程

AOF文件写入流程大致分为三步:

  1. 将数据写入AOF缓存,实质是一个sds数据
  2. 将AOF缓存刷入磁盘缓冲区(page cache)中
  3. 刷盘

image-20241028212538059

AOF重写

随着用户的请求逐渐积累,AOF文件会逐渐膨胀,但是AOF文件中有效记录是少量的。这是因为,对一个key修改成千上万次,只有最后一次修改是有效的,需要真正保存在AOF文件中,而之前的修改都是无效的。所以,完全可以将AOF文件中的无效记录删除,避免AOF文件过于庞大。

AOF重写过程可以概括为一次拷贝,两处缓冲

  • 一次拷贝:重写发生时,主进程会fork出一个子进程,子进程和主进程共享Redis物理内存,让子进程将这些内存写入重写日志
  • 两处缓冲:在重写过程中,如果有新的写入请求,会由主进程分别写入AOF缓冲和AOF重写缓冲。AOF缓冲用于保证即使此时发生宕机,原来的AOF日志也是完整的,可用于恢复。AOF重写缓冲用于保证新的AOF文件不会丢失最新的写入操作
image-20241028213530151

AOF混合持久化

AOF混合持久化是指,在AOF重写阶段,Redis将现阶段的数据状态保存为RDB状态的二进制数据,并写入AOF文件,然后再将AOF重写缓冲区中的日志数据写入到AOF文件,最后把新生成的AOF文件替换掉旧的AOF文件。

此时的AOF文件既包含二进制数据,又包含日志数据,所以叫做混合持久化。

AOF混合持久化通过降低AOF文件的可读性,用二进制数据记录数据状态,减少了AOF文件的体积大小。