持久化

Redis 有 RDB 和 AOF 两种持久化方式,持久化功能有效的避免因进程退出造成的数据丢失问题,下次重启时利用以前持久化的文件即可恢复数据。

RDB:

将数据以快照的形式保存下来。触发方式为手动触发和自动触发。

手动触发:

手动触发分别对应 save 和 bgsave 命令。

  1. save 命令:阻塞当前服务器,直到 RDB 过程完成为止,对于内存 比较大的实例会造成长时间阻塞,线上环境不建议使用。
  2. bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子 进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时间很短。

自动触发:

  1. 使用 save 相关配置,如“save m n”。表示 m 秒内数据集存在 n 次修改 时,自动触发 bgsave。
  2. 如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。(主从复制时)
  3. 执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作。
  4. 默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则 自动执行 bgsave。

优点:

  1. RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据 快照。非常适用于备份,全量复制等场景。比如每 6 小时执行 bgsave 备份, 并把 RDB 文件拷贝到远程机器或者文件系统中(如 hdfs),用于灾难恢复。
  2. Redis 加载 RDB 恢复数据远远快于 AOF 的方式。

缺点:

  1. RDB 方式数据没办法做到实时持久化/秒级持久化。因为 bgsave 每次运 行都要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。
  2. RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式 的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题。

AOF:

以独立日志的方式,记录每次写命令,重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。AOF 的主要作用 是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式。
开启 AOF 功能需要设置配置:appendonly yes,默认不开启。

AOF 的工作流程操作:

命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load):

  1. 所有的写入命令会追加到 aof_buf(缓冲区)中。不直接写到磁盘文件是为了提升效率,是磁盘负载不成为性能瓶颈。还有另一个好处,Redis 可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡。
  2. AOF 缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  4. 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

重写后的 AOF 文件为什么可以变小?

执行 bgrewriteaof 命令可以重写 AOF 文件。

  1. 进程中已经超时的文件不在写入。
  2. 旧的 AOF 文件含有无效命令,重写使用进程内数据直接生成,这样新的 AOF 文件只保留最终数据的写入命令。
  3. 多条写命令可以合并为一个,为了防止单条命令过大造成客户端缓冲区溢 出,对于 list、set、hash、zset 等类型操作,以 64 个元素为界拆分为多条。

AOF 重写降低了文件占用空间,除此之外,另一个目的是:更小的 AOF 文件可以更快地被 Redis 加载。
手动触发:直接调用 bgrewriteaof 命令。
自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。自动触发时机=aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewritepercentage。

启动流程:

  1. AOF 持久化开启且存在 AOF 文件时,优先加载 AOF 文件。
  2. AOF 关闭或者 AOF 文件不存在时,加载 RDB 文件。
  3. 加载 AOF/RDB 文件成功后,Redis 启动成功。
  4. AOF/RDB 文件存在错误时,Redis 启动失败并打印错误信息。