Redis 学习笔记(篇七):Redis 持久化
因为 Redis 是内存数据库,它将自己的数据储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据也将会丢失,为了解决这个问题,Redis 提供了持久化的功能。
Redis 中的持久化有两种,分别是 RDB 和 AOF。
RDB 持久化
RDB 是将 Redis 内存中的快照直接保存到磁盘中,避免数据丢失。
RDB 文件的创建
RDB 文件是一个经过压缩的二进制文件。有两个命令可以生产 RDB 文件,一个是 SAVE,另一个是 BGSAVE。
SAVE 命令会阻塞 Redis 服务器进程,直到 RDB 文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求。
BGSAVE 命令会派生出一个子进程,然后由子进程负责创建 RDB 文件,服务器进程(父进程)继续处理命令请求。
除了主动执行命令之外,Redis 还可以根据配置自动进行 RDB 持久化。如果我们向服务器有如下配置(默认就有):
save 900 1
save 300 10
save 60 10000
那么只要满足以下三个条件中的任意一个,BGSAVE 命令就会被执行:
- 服务器在 900 秒之内,对数据库进行了至少 1 次修改。
- 服务器在 300 秒之内,对数据库进行了至少 10 次修改。
- 服务器在 60 秒之内,对数据库进行了至少 10000 次修改。
RDB 文件的载入
RDB 文件的载入工作是在服务器启动时自动执行的,所以 Redis 并没有专门用于载入 RDB 文件的命令,只要 Redis 服务器在启动时检查到 RDB 文件,就会自动载入。
另外值得一提的是,因为 AOF 文件的更新频率通常比 RDB 文件的更新频率高,所以:
- 如果服务器开启了 AOF 持久化功能,那么服务器会优先使用 AOF 文件来还原数据库状态。
- 只有在 AOF 持久化功能处于关闭状态时,服务器才会使用 RDB 文件来还原数据库状态。
如下图所示(出自《Redis设计与实现第二版》第十章:RDB持久化):
AOF 持久化
和 RDB 持久化不同,AOF 持久化是通过保存 Redis 服务器所执行的谢明令来记录数据库状态的,如下图所示(出自《Redis设计与实现第二版》第十一章:AOF持久化):
AOF 持久化的实现
当 AOF 持久化功能处于打开状态时,服务器在执行完一个写命令之后,会讲被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾。
Redis 服务器会每隔 100ms 将 aof_buf 缓冲区的内容真正写入到 AOF 文件里面。
AOF 持久化的效率和安全性
服务器配里 appendfsync 选项的值直接决定 AOF 持久化功能的效率和安全性。
- 当 appendfsyn 的值为 always 时,服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,并且同步 AOF 文件,所以 always 的效率是 aPPendfsync 选项三个值当中最慢的一个,但从安全性来说, always 也是最安全的,因为即使出现故障停机, AOF 持久化也只会丢失一个事件循环中所产生的命令数据。
- 当 appendfsync 的值为 everysec 时,服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,并且每隔一秒就要在子线程中对 AOF 文件进行一次同步。从效率上来讲, everysec 模式足够快,并且就算出现故障停机,数据库也只丢失一秒钟的命令数据。
- 当 appendfsync 的值为 no 时,服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,至于何时对 AOF 文件进行同步,则由操作系统控制。因为处于 no 模式下的 flushAppendonlyFile 调用无须执行同步操作,所以该模式下的 AOF 文件写入速度总是最快的,不过因为这种模式会在系统缓存中积取一段时间的写入数据,所以该模式的单次同步时长通常是三种模式中时间最长的。从平摊操作的角度来看, no 模式和 everysec 模式的效率类似,当出现故障停机时,使用 no 模式的服务器将丢失上次同步 AOF 文件之后的所有写命令数据。
AOF 文件的载入与数据还原
因为 AOF 文件里面包含了重建数据库状态所需的所有写命令, 所以服务器只要读入并重新执行一遍 AOF 文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。
AOF 文件载入过程如下(出自《Redis设计与实现第二版》第十一章:AOF持久化):
AOF 文件的重写
因为 AOF 持久化是通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝, AOF 文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大的 AOF 文件很可能对 Redis 服务器、甚至整个宿主计算机造成影响,并且 AOF 文件的体积越大,使用 AOF 文件来进行数据还原所需的时间就越多。
为了解决 AOF 文件体积过大的问题,Redis 提供了 AOF 文件重写功能。即服务器可以创建一个新的 AOF 文件来代替现有的 AOF 文件,但由于新的 AOF 文件不会包含任何浪费空间的冗余命令(即只有写命令,没有del命令等),所以新 AOF 文件的体积通常比旧 AOF 文件的体积小得多。