Redis 持久化

Redis 持久化

Redis 提供了一系列不同的持久性选项:

  • RDB(Redis 数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
  • AOF(Append Only File):AOF持久化记录服务器收到的每一个写操作,在服务器启动时会再次播放,重建原始数据集。命令使用与 Redis 协议本身相同的格式以仅附加的方式记录。当日志变得太大时,Redis 能够在后台重写日志。
  • 无持久性:如果您希望数据在服务器运行时一直存在,您可以完全禁用持久性。
  • RDB + AOF:可以在同一个实例中组合 AOF 和 RDB。请注意,在这种情况下,当 Redis 重新启动时,将使用 AOF 文件来重建原始数据集,因为它保证是最完整的。

要理解的最重要的事情是 RDB 和 AOF 持久性之间的不同权衡。让我们从 RDB 开始:

RDB优势

  • RDB 是 Redis 数据的非常紧凑的单文件时间点表示。RDB 文件非常适合备份。例如,您可能希望在最近 24 小时内每小时存档一次 RDB 文件,并在 30 天内每天保存一个 RDB 快照。这使您可以在发生灾难时轻松恢复不同版本的数据集。
  • RDB 非常适合灾难恢复,它是一个可以传输到远程数据中心或 Amazon S3(可能已加密)的紧凑文件。
  • RDB 最大限度地提高了 Redis 的性能,因为 Redis 父进程为了持久化需要做的唯一工作是派生一个将完成所有其余工作的子进程。父实例永远不会执行磁盘 I/O 或类似操作。
  • 与 AOF 相比,RDB 允许更快地重新启动大数据集。
  • 在副本上,RDB 支持重启和故障转移后的部分重新同步

RDB 的缺点

  • 如果您需要在 Redis 停止工作(例如断电后)时将数据丢失的可能性降至最低,那么 RDB 并不好。您可以在生成 RDB 的地方配置不同的保存点(例如,在对数据集进行至少 5 分钟和 100 次写入之后,但您可以有多个保存点)。但是,您通常会每五分钟或更长时间创建一个 RDB 快照,因此,如果 Redis 因任何原因没有正确关闭而停止工作,您应该准备好丢失最近几分钟的数据。
  • RDB 经常需要 fork() 以便使用子进程在磁盘上持久化。如果数据集很大,Fork() 可能会很耗时,如果数据集很大且 CPU 性能不是很好,可能会导致 Redis 停止为客户端服务几毫秒甚至一秒钟。AOF 也需要 fork() 但你可以调整你想要重写日志的频率,而不会对持久性进行任何权衡。

AOF优势

  • 使用 AOF Redis 更持久:你可以有不同的 fsync 策略:根本没有 fsync,每秒 fsync,每次查询 fsync。使用 fsync 每秒写入性能的默认策略仍然很棒(fsync 是使用后台线程执行的,当没有 fsync 正在进行时,主线程将努力执行写入。)但您只能丢失一秒钟的写入。
  • AOF 日志是仅附加日志,因此在断电时不会出现寻道或损坏问题。即使日志由于某种原因(磁盘已满或其他原因)以半写命令结束,redis-check-aof 工具也能够轻松修复它。
  • 当 AOF 变得太大时,Redis 能够在后台自动重写。重写是完全安全的,因为当 Redis 继续追加到旧文件时,会使用创建当前数据集所需的最少操作集生成一个全新的文件,一旦第二个文件准备就绪,Redis 就会切换这两个文件并开始追加到新的那一个。
  • AOF 以易于理解和解析的格式包含所有操作的日志。您甚至可以轻松导出 AOF 文件。例如,即使您不小心使用FLUSHALL命令刷新了所有内容,只要在此期间没有重写日志,您仍然可以通过停止服务器、删除最新命令并重新启动 Redis 来保存您的数据集再次。

AOF的缺点

  • AOF 文件通常比相同数据集的等效 RDB 文件大。
  • AOF 可能比 RDB 慢,具体取决于确切的 fsync 策略。一般来说,将 fsync 设置为每秒性能仍然非常高,并且禁用 fsync 后,即使在高负载下,它也应该与 RDB 一样快。即使在巨大的写入负载的情况下,RDB 仍然能够提供关于最大延迟的更多保证。
  • 过去我们在特定命令中遇到过罕见的错误(例如有一个涉及阻塞命令的错误,如BRPOPLPUSH) 导致生成的 AOF 在重新加载时无法重现完全相同的数据集。这些错误很少见,我们在测试套件中进行了测试,自动创建随机复杂数据集并重新加载它们以检查一切正常。但是,使用 RDB 持久性几乎不可能出现此类错误。为了更清楚地说明这一点:Redis AOF 通过增量更新现有状态来工作,就像 MySQL 或 MongoDB 那样,而 RDB 快照一次又一次地从头开始创建所有内容,这在概念上更加健壮。但是 – 1)需要注意的是,每次Redis重写AOF时,都是从数据集中包含的实际数据开始重新创建,与始终附加的 AOF 文件(或重写读取旧 AOF 而不是读取内存中的数据)相比,对错误的抵抗力更强。2) 我们从未收到过用户关于在现实世界中检测到的 AOF 损坏的单一报告。