Redis 持久化

由于 Redis 是内存数据库,如果不将数据持久化到硬盘上,在进程中断时就会导致数据丢失。

关于 Redis 持久化的详细内容参考官方文档:Redis persistence

RDB (Redis Database)

RDB 持久化以指定的时间间隔执行数据集的时间点快照。

rdb 文件生成方式:

  • 满足 save 的规则

  • 执行 flushall 命令

  • 使用 shutdown 退出 redis

rdb 文件数据恢复:

  • 将 rdb 文件放在 redis 的启动目录下,在 redis 启动时就会自动加载

RDB 的运行方式

每当 Redis 需要将数据集转储到磁盘时,就会发生以下情况:

  • Redis forks。我们现在有一个子进程和一个父进程。

  • 子进程开始将数据集写入临时 RDB 文件。

  • 当子进程写完新的 RDB 文件时,它会替换旧的。

RDB 的优势

  • RDB 是 Redis 数据的非常紧凑的单文件时间点表示。RDB 文件非常适合备份。例如,您可能希望在最近 24 小时内每小时归档一次 RDB 文件,并在 30 天内每天保存一个 RDB 快照。这使您可以在发生灾难时轻松恢复不同版本的数据集。

  • RDB 非常适合灾难恢复,它是一个可以传输到远程数据中心或 Amazon S3(可以加密)的紧凑文件。

  • RDB 最大限度地提高了 Redis 的性能,因为 Redis 父进程为了持久化需要做的唯一工作就是创建一个子进程,它会完成所有剩下的工作。父进程永远不会执行磁盘 I/O 或类似操作。

  • 与 AOF 相比,RDB 允许更快地重新启动大数据集。

RDB 的缺点

  • 如果您需要在 Redis 停止工作(例如停电后)的情况下将数据丢失的可能性降到最低,则 RDB 并不适用。您可以在生成 RDB 的地方配置不同的保存点(例如,在至少五分钟和对数据集进行 100 次写入后,您可以有多个保存点)。但是,您通常会每五分钟或更长时间创建一个 RDB 快照,因此如果 Redis 因任何原因在没有正确关闭的情况下停止工作,您应该做好丢失最新分钟数据的准备。

  • RDB 需要经常 fork() 以便使用子进程持久保存在磁盘上。如果数据集很大,fork() 可能会很耗时,如果数据集很大且 CPU 性能不佳,可能会导致 Redis 停止为客户端提供几毫秒甚至一秒的服务。AOF 也需要 fork() 但频率较低,您可以调整重写日志的频率,而无需在持久性上做出任何权衡。

AOF (Append Only File)

快照不是很耐用。如果运行 Redis 的计算机停止运行,电源线出现故障,或者您不小心kill -9将实例写入 Redis,那么最新写入 Redis 的数据将会丢失。虽然这对于某些应用程序来说可能不是什么大问题,但存在完全持久性的用例,在这些情况下,单独使用 Redis 快照并不是一个可行的选择。

仅附加文件是 Redis 的另一种完全持久的策略。它在 1.1 版中可用。

您可以在配置文件中开启 AOF:

appendonly yes

从现在开始,每次 Redis 收到更改数据集的命令(例如SET)时,它都会将其附加到 AOF。当你重启 Redis 时它会重新播放 AOF 来重建状态。

从 Redis 7.0.0 开始,Redis 使用了 multi-part AOF 机制。即,将原来的单个AOF文件拆分为基础文件(最多一个)和增量文件(可能不止一个)。基础文件表示重写 AOF 时存在的数据的初始(RDB 或 AOF 格式)快照。增量文件包含自上次创建基本 AOF 文件以来的增量更改。所有这些文件都放在一个单独的目录中,并由一个清单文件进行跟踪。

AOF 的运行方式

日志重写使用已用于快照的相同写时复制技巧。它是这样工作的:

Redis >= 7.0

  • Redis forks,所以现在我们有一个子进程和一个父进程。

  • 子进程开始在临时文件中写入新的基础 AOF。

  • 父进程打开一个新的增量 AOF 文件继续写入更新。如果重写失败,旧的基础文件和增量文件(如果有的话)加上这个新打开的增量文件代表了完整的更新数据集,所以我们是安全的。

  • 当孩子完成重写基础文件时,父进程得到一个信号,并使用新打开的增量文件和子进程生成的基础文件来构建一个临时清单,并将其持久化。

  • 现在 Redis 对清单文件进行原子交换,以便此 AOF 重写的结果生效。Redis 还会清理旧的基本文件和任何未使用的增量文件。

Redis < 7.0

  • Redis forks,所以现在我们有一个子进程和一个父进程。

  • 子进程开始在临时文件中写入新的 AOF。

  • 父进程在内存缓冲区中累积所有新更改(但同时它会将新更改写入旧的仅附加文件,因此如果重写失败,我们是安全的)。

  • 当子进程完成文件重写后,父进程收到一个信号,并将内存缓冲区附加到子进程生成的文件的末尾。

  • 现在 Redis 自动将新文件重命名为旧文件,并开始将新数据附加到新文件中。

AOF 的优势

  • 使用 AOF Redis 更持久:您可以有不同的 fsync 策略:根本没有 fsync,每秒 fsync,每次查询都 fsync。使用每秒 fsync 的默认策略,写入性能仍然很好。fsync 是使用后台线程执行的,主线程将在没有 fsync 进行时努力执行写入,因此您只能损失一秒钟的写入。

  • AOF 日志是一个仅追加日志,因此没有查找,也没有断电时的损坏问题。即使由于某种原因(磁盘已满或其他原因)日志以写入一半的命令结束,redis-check-aof 工具也能够轻松修复它。

  • 当 AOF 变得太大时,Redis 能够在后台自动重写 AOF。重写是完全安全的,因为当 Redis 继续附加到旧文件时,会生成一个全新的文件,使用创建当前数据集所需的最少操作集,一旦第二个文件准备就绪,Redis 就会切换这两个文件并开始附加到新的那一个。

  • AOF 以易于理解和解析的格式包含一个接一个地记录所有操作的日志。您甚至可以轻松导出 AOF 文件。例如,即使您不小心使用该FLUSHALL命令刷新了所有内容,只要在此期间没有执行日志重写,您仍然可以通过停止服务器、删除最新命令并再次重新启动 Redis 来保存您的数据集.

AOF 的缺点

  • 对于相同的数据集,AOF 文件通常比等效的 RDB 文件大。

  • 根据确切的 fsync 策略,AOF 可能比 RDB 慢。一般来说,将 fsync 设置为每秒一次的性能仍然非常高,并且在禁用 fsync 的情况下,即使在高负载下,它也应该与 RDB 一样快。即使在巨大的写入负载的情况下,RDB 仍然能够提供更多关于最大延迟的保证。

应该用哪种方式?

您应该同时使用这两种持久化方法的一般指示是,如果您希望获得与 PostgreSQL 可以提供的数据安全程度相当的数据安全性。

如果你非常关心你的数据,但仍然可以忍受在发生灾难时丢失几分钟的数据,那么你可以简单地单独使用 RDB。

有许多用户单独使用 AOF,但我们不鼓励这样做,因为时不时地创建一个 RDB 快照对于进行数据库备份、更快的重启以及在 AOF 引擎中出现错误时是一个好主意。

最后更新于