新手村:Redis进阶篇二——持久化

Redis进阶篇二——持久化

1. 简介

持久化即将数据保存到可永久保存的存储设备中。咱们知道 Redis 为了保证效率而把数据都缓存在内存中,但当咱们重启系统或关闭系统后,缓存在内存中的数据都会消失,因此为了让有些数据能保留下,Redis 持久化存储就应运而生。Redis 提供了两种方式进行持久化,一种是RDB 持久化,另外一种是 AOF(append only file) 持久化,下面咱们逐一介绍。web

2. RDB 持久化

RDB 是 Redis 默认的持久化机制,它的工做原理是把当前内存中的数据生成快照 (snapshot) 的方式写入磁盘中的二进制文件中,默认的文件名为 dump.rdb。恢复时将快照文件直接读到内存中。RDB 有两种触发方式,分别是自动触发和手动触发。redis

2.1 自动触发

自动触发使用 save 相关配置触发,好比 “save m n”,表示在 m 秒内数据库存在 n 次修改时,自动触发BGSAVE (BGSAVE 命令在手动触发时会介绍)。 Redis 默认配置以下:数据库

save 900 1      # 在 900 秒内若是至少有 1 个 key 的值变化,则触发
save 300 10 # 在 300 秒内若是至少有 10 个 key 的值变化,则触发 save 60 10000 # 在 60 秒内若是至少有 10000 个 key 的值变化,则触发 复制代码

当实际操做知足配置的 save 形式时就会进行 RDB 持久化,将当前的数据快照保存。windows

2.2 手动触发

手动触发进行 RDB 持久化涉及到两个 Redis 服务器命令:缓存

  1. SAVE:执行一个同步保存操做,将当前 Redis 实例的全部数据快照以 RDB 文件的形式保存到磁盘中。
  2. BGSAVE:用于在后台异步保存当前数据库的数据到磁盘。

SAVE 命令因为是同步操做,所以会阻塞当前 Redis 服务器知道 RDB 持久化过程完成为止,对于内存比较大的实例会形成长时间阻塞,不建议在线上环境使用。 BGSAVE 命令会执行 fork 操做建立一个子进程,由子进程完成 RDB 持久化过程,完成后自动结束,阻塞只发生在 fork 过程,通常时间很短。 基本上 Redis 内部的 RDB 操做都是采用 BGSAVE 命令。安全

2.3 RDB 优缺点

RDB 的优势:服务器

  • RDB 文件是一个紧凑压缩的二进制文件,它保存了 Redis 在某个时间点的数据,比较适合进行备份和灾难恢复。
  • 生成 RDB 文件的过程是由父进程 fork 操做建立的一个子进程完成,父进程仍然能够接受其余命令请求,不用进行任何磁盘 IO 操做。
  • 因为 RDB 文件是二进制文件,所以在恢复数据集时速度更快。

RDB 的缺点:app

  • RDB 没法作到实时持久化/秒级持久化。由于 BGSAVE 命令须要执行 fork 操做建立子进程,若是频繁操做必然会占用大量内存,执行成本太高,反而使性能下降。
  • RDB 文件使用特定二进制格式保存,Redis 版本演进过程当中有多个格式的 RDB 版本,容易出现版本不兼容问题。
  • RDB 是隔一段时间进行备份,若是 Redis 在备份时出现意外宕机,那么就会失去最后一次快照的数据。

3. AOF 持久化

差异于经过保存数据库中的键值对的 RDB 持久化方式,AOF 持久化是经过保存 Redis 服务器所执行的写命令来记录数据库状态,重启时再从新执行 AOF 文件中的命令以完成数据恢复。AOF 的主要做用是解决了数据持久化的实时性,目前已是 Redis 持久化的主流方式。异步

3.1 使用 AOF

Redis 中 AOF 是默认关闭的,使用前要将配置参数 appendonly 改成 yes(5.3 中会涉及一些配置参数,配置文件是安装目录下的 redis.windows.conf,参数在 APPEND ONLY FILE 一栏)。AOF 文件的保存文件名经过参数 appendfilename 参数配置,默认是 appendonly.aof。AOF 持久化策略的选择由 appendfsync 参数进行选择,有下面几种:编辑器

  • no:不执行 fsync,由操做系统保证数据同步到磁盘,速度快但不安全。
  • always:每次写入都执行 fsync,虽然保证数据同步到磁盘,可是效率很低。
  • everysec:默认配置,每秒执行一次 fsync,可能会丢失这 1 秒的数据,但兼顾了安全性和效率,最经常使用的选择。

3.2 AOF工做流程

AOF 的工做流程操做:命令写入 (append)、文件同步 (sync)、文件重写 (rewrite)、重启加载 (load)。 首先,全部的写入命令都会被追加到 AOF 缓冲区中,而后 AOF 缓冲区根据对应的持久化策略对磁盘进行文件同步操做。当 AOF 文件的大小超过所设定的重写阈值时对 AOF 文件进行重写。当须要重写时,父进程会进行 fork 操做建立一个子进程,子进程带有父进程的数据副本,由子进程完成重写过程,在此期间父进程仍然能够处理其余命令。 当咱们重启 Redis 服务器时,能够加载 AOF 文件进行数据恢复,流程以下:

持久化
持久化

从上图咱们也能够得知,在同时开启了 RDB 和 AOF 的状况下,Redis 会优先 AOF 文件的加载。遇到异常时,可使用修复命令 redis-check-aof--fix 进行修复。 在上述流程中,咱们有几点须要注意与知晓的:

  1. 为何须要 AOF 缓冲:因为 Redis 自己是单线程工做的,若是每次都直接把写入命令追加到 AOF 文件中,那么此时的性能取决于磁盘的 IO 性能,会下降性能。先写入 AOF 缓冲区中,咱们还能够选择缓冲区同步到磁盘的策略,进一步兼顾安全性和性能。

  2. 为何须要 AOF 重写:因为 AOF 持久化是不断将写命令记录到 AOF 文件中,随着时间的推移,文件必然会愈来愈大,这样会增长恢复时的压力。除此以外,例如一个 key 表示粉丝数,增长粉丝的过程咱们会使用大量自增命令,而实际上在恢复时咱们只须要知道在这段时间内总共增长了多少便可。这个例子也正指明了重写机制的工做原理:AOF 文件重写并不是是对原文件进行整理,而是直接读取服务器中现有的键值对,而后用一条命令代替记录中改键值对的多条命令操做,生成一个新的文件替换原文件

  3. AOF 重写触发机制:AOF 重写也分自动触发和手动触发。

    • 自动触发涉及两个配置参数:一个是 auto-aof-rewrite-percent,默认值是 100;另外一个是 auto-aof-rewrite-min-size,默认值是 64MB。按照默认配置,Redis 会记录上次重写时 AOF 文件大小,并当目前 AOF 文件是上一次重写后大小的一倍且文件大于 64MB 时自动触发。

      auto-aof-rewrite-percent:当目前 AOF 文件大小超过上一次重写的 AOF 文件大小的百分之几时进行重写。 auto-aof-rewrite-min-size:设置容许重写的最小 AOF 文件大小,避免了文件很小却知足百分比要求的重写状况。

    • 手动触发直接调用 BGREWRITEAOF 命令。

3.3 AOF 优缺点

AOF 的优势:

  • 提供了多种同步频率,即便使用默认的同步频率每秒同步一次,Redis 最多也就失去 1 秒的数据。
  • AOF 文件使用 Redis 命令追加的形式来构造,即便只能向 AOF 文件写入命令的片断,也很容易使用redis-check-aof 工具修正。
  • AOF 文件的格式可读性较强,能够为使用者提供更灵活的处理方式。

AOF 的缺点:

  • 在拥有相同数据的状况下,AOF 文件一般会比 RDB 文件体积更大。
  • 当 Redis 负载较高的状况下,RDB 会比 AOD 具备更好的性能保证。
  • RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,所以从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在RDB 没有存在。

4. 如何选择

介绍了 Redis 持久化的两种方式,那么咱们在实际中应该如何选择呢?对于数据库而言,数据是至关重要的,RDB 相比于 AOF 而言出现异常丢失数据可能会更严重,除此以外,选择 RDB 是更好的,定时生成快照是经常使用的数据库备份方式,而且 RDB 文件是二进制文件,在恢复数据集时速度更快,使用 RDB 方式也能够规避 AOF 方式中的一些隐藏 bug。可是在通常状况下,咱们应该同时开启两种持久化方式,而不是单独使用某一种持久化机制。因为一般状况下 AOF 方式保存的数据更具实时性且更完整,所以相比 RDB 文件,Redis 重启时会优先使用 AOF 文件来恢复数据。

最后吟唱

本文使用 mdnice 排版

相关文章
相关标签/搜索