【Redis3.0.x】持久化

Redis3.0.x 持久化

概述

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

  • RDB(Redis DataBase)持久化,可以在指定的时间间隔内生成数据集的时间点快照。
  • AOF(Append Only File)持久化,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。Redis 还可以在后台对 AOF 文件进行重写,使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
  • 可以同时使用 RDB 和 AOF 持久化,当 Redis 重启时,它会优先使用 AOF 文件来还原数据集,因为 AOF 文件 通常比 RDB 文件保存的数据集更完整。

fork:它的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

RDB

RDB 优点

RDB 优点:

  • RDB 是一种表示某个即时点的 Redis 数据的紧凑文件,RDB文件适合用于备份
  • RDB 非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。
  • RDB 最大化了 Redis 的性能,因为 Redis 父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像 磁盘 IO 这样的操作。
  • RDB 在重启时还原数据集比 AOF 要快。

RDB 缺点

RDB 缺点:

  • RDB 可能不能很好的完成最小化数据丢失。
  • RDB 需要经常调用 fork 子进程来持久化到磁盘,如果数据集很大的话,fork 会比较耗时。

RDB 快照

默认情况下,Redis 保存数据集快照到磁盘,默认名为 dump.rdb 的二进制文件。可以设置让 Redis 在 N 秒内至少有 M 次数据集改动时 保存数据集,或者也可以手动调用 SAVE 或者 BGSAVE 命令进行快照保存。使用 config set save "" 关闭 RDB 持久化。

其中,使用 SAVE 时只管保存,其它不管,全部阻塞。使用 BGSAVE 会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过 lastsave 命令获取最后一次成功执行快照的时间。

RDB 使用

正常还原数据集

  • 开启 RDB 持久化
  • 将 RDB 备份文件复制到安装目录,使用 config get dir 获得安装目录
  • 重启 Redis 然后重新加载

异常还原数据集

  • 开启 RDB 持久化
  • 将 RDB 备份文件复制到安装目录
  • 使用 redis-check-rdb --fix 对文件进行修复
  • 重启 Redis 然后重新加载

快照的运行方式

当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:

  • Redis 调用 fork,同时拥有父进程和子进程。
  • 子进程将数据集写入到一个临时 RDB 文件中。
  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

AOF

AOF 优点

AOF 优点:

  • AOF 能很好的完成最小化数据丢失。
  • AOF 是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令,使用 redis-check-aof 工具也可以很轻易的修复。
  • AOF 变得很大时,Redis 会自动在后台进行重写
  • AOF 里面包含一个个的操作,以易于理解和解析的格式存储,可以轻易的导出一个 AOF。

AOF 缺点

AOF 缺点:

  • 对同样的数据集,AOF 通常要大于 RDB。
  • AOF 可能比 RDB 慢,不过这取决于准确的 fsync 策略。有三种 fsync 策略:每次有新命令追加到 AOF 时就执行一次 fsync,非常慢但非常安全每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据从不 fsync,将数据交给操作系统来处理。最快但不安全

AOF 使用

使用 config set appendonly yes/no 开启或关闭 AOF 持久化。

正常还原数据集

  • 开启 AOF 持久化
  • 将 AOF 备份文件复制到安装目录
  • 重启 Redis 然后重新加载

异常还原数据集

  • 开启 AOF 持久化
  • 将 AOF 备份文件复制到安装目录
  • 使用 redis-check-aof --fix 对文件进行修复
  • 重启 Redis 然后重新加载

AOF 重写

AOF 重写是绝对安全的,因为 Redis 继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis 就会切换这两个文件,并开始往新文件追加。

重写的运行方式

和快照的运行方式类似,当需要 AOF 重写时,服务器执行以下操作:

  • Redis 调用 fork,同时拥有父进程和子进程。
  • 子进程开始向一个临时文件中写 AOF。
  • 父进程在一个内存缓冲区中积累新的变更,同时将新的变更写入旧的 AOF。
  • 当子进程完成重写文件,父进程收到一个信号,追加内存缓冲区到子进程创建的文件末尾。
  • 最后 Redis 原子性地重命名旧文件为新的,然后开始追加新数据到新文件。

触发重写的机制:

  • Redis 会记录上次重写时的 AOF 大小,默认配置是当 AOF 大小是上次 rewrite 后大小的一倍,并且文件大于 64M 时触发。

RDB 转换到 AOF

大致步骤为:

  • 创建最近的 RDB 文件的备份,并将备份保存到安全位置。
  • 执行 config set appendonly yes,开启 AOF,
  • 执行 config set save "",关闭 RDB,这一步是可选的。

RDB 和 AOF 的相互作用

Redis2.4 以上的版本会确保在 RDB 快照创建时不触发 AOF 重写,或者在 AOF 重写时不允许 BGSAVE 操作,以避免 Redis 后台进程同时做繁重的磁盘I /O 操作。

当创建 RDB 快照时对于用户使用 BGREWRITEAOF 明确发起的日志重写操作,server 会立刻回应一个 状态码 告知用户操作将会被执行,并且是在快照创建完成后,重写操作开始被执行。

性能建议

因为 RDB 文件只用作后背用途,建议只在 Slave 上持久化 RDB 文件,而且只要 15 分钟备份一次就可以了,即 save 900 1

如果开启 AOF,好处是在最坏的情况下也只会丢失不超过两秒的数据,而且启动脚本较简单,载入自己的那个 AOF 文件。代价是带来了持续的 IO,而且 AOF rewrite 过程中将产生的新数据写到新文件造成的阻塞几乎是不可避免的。并且只要硬盘许可,应该尽量减少 AOF rewrite 的频率,AOF 重写的基础大小默认值为 64M,显然太小了,可以设置到 5G 以上,而且还要修改重写率。

如果不开启 AOF,仅靠 Master-Slave Replication 实现高可用性也可以。好处是省掉了 IO,同时减少了 rewrite 过程对系统带来的影响。代价是如果 Master-Slave 同时挂掉,会丢失十几分钟的数据,而且启动脚本较复杂,需要比较 Master-Slave 的两个 RDB 文件,载入较新的那个 RDB 文件。

练习和总结

原文地址:https://www.cnblogs.com/parzulpan/p/14215141.html