Redis学习笔记 – 数据持久化

Redis 是内存数据库,它将数据储存在内存中,如果不将数据保存到磁盘里,那么一旦进程退出,服务器里的数据就会丢失。

为了解决这个问题,Redis 提供了两种数据持久化功能:

  • RDB 持久化
  • AOF 持久化

RDB 持久化

RDB持久化可以将Redis在内存中的数据,保存到磁盘里的RDB文件中,假如Redis服务器进程意外退出,只要RDB文件存在,就可以用它来还原数据。

RDB文件的创建

Redis 有两条命令来创建RDB文件,一个SAVE,另一个是 BGSAVE

SAVE 命令会阻塞Redis 服务器进程,直到RDB文件创建完毕。

BGSAVE 命令不会阻塞Redis服务器进程,该命令会派生出一个子进程,由子进程负责创建RDB文件。

自动间隔性保存

通过配置Redis服务器的Save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。

可以通过Save选项设置多个保存条件,只要其中任意一个条件满足,服务器就会执行BGSAVE命令。

如果没有主动设置Save选项,Redis服务器会为Save选项设置默认值。

RDB文件的载入

RDB文件会在Redis服务器启动时自动载入, Redis没有专门的用于载入RDB文件的命令。

Redis服务器载入RDB文件时,会处于阻塞状态,直到载入完毕。


AOF(Append Only File) 持久化

与RDB持久化不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据的。

AOF持久化的实现:

AOF的实现,分为命令追加(append)、文件写入、文件同步三个步骤。

命令追加

服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾

文件写入和同步

服务器在执行写命令后,使得一些内容被追加到 aof_buf 缓冲区里面,在每个事件循环结束前,根据服务器配置选项 appendfsync 选项的值,来决定是否将 aof_buf缓冲区的内容写入并保存到AOF文件。

appendfsync不同的值所产生的不同的持久化行为:

appendfsync选项的值 flushAppendOnlyFile函数的行为 效率和安全性
always 将aof_buf缓冲区中的所有内容写入并同步到AOF文件 效率最慢,安全性最高
everysec 将aof_buf缓冲区中的所有内容写入AOF文件,如果上次同步AOF文件的时间距离现在超过一秒钟,那么再次对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的 足够快,假如出现故障,只丢失一秒钟的命令数据
no 将aof_buf缓冲区的所有内容写入到AOF文件,但并不对AOF文件进行同步,由操作系统来决定何时同步 写入速度最快;当出现故障时,将丢失上次同步AOF文件之后的所有写命令

AOF文件的载入和数据还原

AOF文件里包含了重建数据的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里保存的写命令,就可以还原服务器关闭之前的数据库状态了。

AOF重写

随着服务器运行时间的增加,AOF文件中的内容会越来越多,文件体积会越来越大,如果不加以控制,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响,并且AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。

为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写功能。通过该功能,Redis服务器会创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积小得多。

从Redis2.4开始,Redis服务器会自动触发AOF重写,不过你可以使用 BGREWRITEAOF 命令来随时触发AOF重写,该命令会派生一个子进程来执行AOF重写,这样Redis服务器可以继续处理命令请求。

不过使用子进程会导致一个问题,子进程在进行AOF重写期间,服务器仍然在处理命令请求,而新的命令可能会对现有的数据库状态进行修改,使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决这一问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器重建子进程之后启用,当Redis服务器执行完一个写命令后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。当子进程完成AOF重写工作后,它会向父进程发送一个信号,父进程在接到该信号后,会执行以下工作:

将AOF重写缓冲区中的所有内容写入新的AOF文件中,这时新的AOF文件所保存的数据库状态和服务器当前的数据库状态一致

对新的AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的替换

在执行步骤1和2时,服务器处于阻塞状态。

Built with Hugo
主题 StackJimmy 设计