redis从入门到实战(5)-redis数据持久化

  |   0 评论   |   13 浏览

Redis持久化

Redis提供了不同的持久性选项范围:

  • RDB持久性按指定的时间间隔执行数据集的时间点快照。
  • AOF持久性会记录服务器接收的每个写入操作,这些操作将在服务器启动时再次播放,以重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且采用仅追加方式。当日志太大时,Redis可以在后台重写日志。
  • 如果您希望,只要您的数据在服务器运行时就一直存在,则可以完全禁用持久性。
  • 可以在同一实例中同时合并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的缺点

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

AOF的优势

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

AOF的缺点

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

好的,那我该怎么用?

通常的指示是,如果您希望获得与PostgreSQL可以提供的功能相当的数据安全性,则应同时使用两种持久性方法。

如果您非常关心数据,但是在灾难情况下仍然可以承受几分钟的数据丢失,则可以仅使用RDB。

有很多用户单独使用AOF,但是我们不建议这样做,因为不时拥有RDB快照对于进行数据库备份,加快重启速度以及AOF引擎中存在错误是一个好主意。

注意:由于所有这些原因,我们将来可能会最终将AOF和RDB统一为一个持久性模型(长期计划)。

以下各节将说明有关这两个持久性模型的更多详细信息。

快照

默认情况下,Redis将数据集的快照保存在磁盘上名为的二进制文件中dump.rdb。您可以配置Redis,使其在数据集中至少有M个更改时每N秒保存一次数据集,也可以手动调用SAVEBGSAVE命令。

例如,如果更改了至少1000个键,此配置将使Redis每60秒自动将数据集转储到磁盘上:

save 60 1000

这种策略称为快照

这个怎么运作

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

  • Redis 叉子。现在,我们有一个孩子和一个父过程。

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

  • 当孩子完成新的RDB文件的写入后,它将替换旧的RDB文件。

此方法使Redis可以受益于写时复制语义。

仅追加文件

快照不是很持久。如果运行Redis的计算机停止运行,电源线出现故障或kill -9实例意外运行,则写入Redis的最新数据将丢失。尽管这对于某些应用程序可能不是什么大问题,但有些使用案例具有充分的耐用性,在这些情况下,Redis并不是可行的选择。

只追加文件是Redis的选择,完全耐用的策略。它在1.1版中可用。

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

appendonly yes

从现在开始,每次Redis收到更改数据集的命令(例如SET)时,它将添加到AOF。重新启动Redis时,它将重新播放AOF以重建状态。

日志改写

可以猜到,随着执行写操作,AOF越来越大。例如,如果您要增加一个计数器100次,最终将在数据集中包含最终值但在AOF中只有100个条目的单个键结束。不需要其中的99个条目来重建当前状态。

因此,Redis支持一个有趣的功能:它能够在后台重建AOF,而不会中断对客户端的服务。每当您发出BGREWRITEAOF时, Redis都会编写最短的命令序列来重建内存中的当前数据集。如果您将AOF与Redis 2.2一起使用,则需要不时运行BGREWRITEAOF。Redis 2.4能够自动触发日志重写(有关更多信息,请参见2.4示例配置文件)。

仅附加文件的持久性如何?

您可以配置Redis将fsync磁盘上的数据进行多少次 。共有三个选项:

  • appendfsync始终:fsync每次将新命令附加到AOF时。非常非常慢,非常安全。
  • appendfsync everysec:fsync每秒。速度足够快(在2.4中可能与快照速度一样快),如果发生灾难,您可能会丢失1秒的数据。
  • appendfsync否:永远不会fsync,只需将数据交到操作系统手中即可。更快,更不安全的方法。通常,Linux使用此配置每30秒刷新一次数据,但这取决于内核的精确调整。

建议(默认)策略是fsync每秒执行一次。它既快速又安全。该always策略在实践中非常慢,但是它支持组提交,因此,如果有多个并行写入,Redis将尝试执行单个fsync操作。

如果我的AOF被截断怎么办?

写入AOF文件时服务器可能崩溃,或者存储AOF文件的卷存储已满。发生这种情况时,AOF仍包含表示数据集给定时间点版本的一致数据(使用默认的AOF fsync策略,该数据可能会过期达一秒钟),但AOF中的最后一条命令可能会被截断。Redis的最新主要版本仍将能够加载AOF,只需丢弃文件中最后一个格式不正确的命令即可。在这种情况下,服务器将发出如下日志:

* Reading RDB preamble from AOF file...
* Reading the remaining AOF tail...
# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 439 !!!
# AOF loaded anyway because aof-load-truncated is enabled

您可以根据需要更改默认配置,以在这种情况下强制Redis停止,但是无论文件中的最后一个命令格式是否正确,默认配置都将继续执行,以确保重新启动后可用。

旧版本的Redis可能无法恢复,并且可能需要执行以下步骤:

  • 制作您的AOF文件的备份副本。

  • 使用redis-check-aofRedis随附的工具修复原始文件:

    $ redis-check-aof --fix

  • (可选)用于diff -u检查两个文件之间的区别。

  • 用固定文件重新启动服务器。

如果我的AOF损坏了怎么办?

如果AOF文件不仅被截断,而且在中间被无效字节序列破坏,那么情况将会更加复杂。Redis将在启动时抱怨并中止:

* Reading the remaining AOF tail...
# Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

最好的办法是运行redis-check-aof实用程序,首先不带--fix选项,然后了解问题,跳转到文件中的给定偏移,并查看是否可以手动修复文件:AOF使用与文件格式相同的格式。 Redis协议,手动修复非常简单。否则,可以让该实用程序为我们修复文件,但是在那种情况下,从无效部分到文件末尾的所有AOF部分都可能被剥离,如果损坏恰好发生,则会导致大量数据丢失。在文件的初始部分。

这个怎么运作

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

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

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

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

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

  • 利润!现在,Redis原子地将旧文件重命名为新文件,并开始将新数据附加到新文件中。

如果我当前正在使用dump.rdb快照,如何切换到AOF?

在Redis 2.0和Redis 2.2中,执行此操作的过程有所不同,因为您可能会认为它在Redis 2.2中更简单,并且根本不需要重新启动。

Redis> = 2.2

  • 备份最新的dump.rdb文件。
  • 将此备份转移到安全的地方。
  • 发出以下两个命令:
  • redis-cli配置集appendonly是
  • redis-cli配置集保存“”
  • 确保您的数据库包含与其包含的相同数量的密钥。
  • 确保正确将写入追加到仅追加文件。

第一个CONFIG命令启用“仅追加文件”。为此,Redis将阻止生成初始转储,然后打开文件进行写入,并将开始附加所有下一个写入查询。

第二个CONFIG命令用于关闭快照持久性。这是可选的,如果您希望可以同时启用两种持久性方法。

**重要信息:**请记住编辑redis.conf以打开AOF,否则当您重新启动服务器时,配置更改将丢失,并且服务器将使用旧配置重新启动。

Redis 2.0

  • 备份最新的dump.rdb文件。
  • 将此备份转移到安全的地方。
  • 停止对数据库的所有写操作!
  • 发出redis-cli bgrewriteaof。这将创建仅追加文件。
  • Redis完成生成AOF转储后,停止服务器。
  • 编辑redis.conf结束启用仅附加文件持久性。
  • 重新启动服务器。
  • 确保您的数据库包含与其包含的相同数量的密钥。
  • 确保正确将写入追加到仅追加文件。

AOF与RDB持久性之间的相互作用

Redis> = 2.4可以确保避免在RDB快照操作正在进行时触发AOF重写,或者在AOF重写正在进行时允许BGSAVE。这样可以防止两个Redis后台进程同时执行大量磁盘I / O。

当进行快照时,用户使用BGREWRITEAOF显式请求日志重写操作时,服务器将以OK状态码答复,告知用户已安排该操作,并且快照完成后将开始重写。

如果同时启用了AOF和RDB持久性,并且Redis重新启动,则AOF文件将用于重建原始数据集,因为它可以保证是最完整的。

备份Redis数据

开始本节之前,请确保阅读以下句子:确保备份数据库。磁盘损坏,云中的实例消失,等等:没有备份意味着数据消失在/ dev / null中的巨大风险。

Redis非常便于数据备份,因为您可以在数据库运行时复制RDB文件:RDB一旦生成就永远不会被修改,而RDB在生成时会使用一个临时名称,并且仅使用rename(2)原子地重命名为其最终目标新快照完成后。

这意味着在服务器运行时,复制RDB文件是完全安全的。这是我们的建议:

  • 在服务器中创建一个cron作业,在一个目录中创建RDB文件的每小时快照,并在另一个目录中创建每日快照。
  • 每次运行cron脚本时,请确保调用find命令以确保删除太旧的快照:例如,您可以每小时拍摄最近48小时的快照,每天拍摄一两个月的快照。确保使用数据和时间信息命名快照。
  • 每天至少有一次确保将RDB快照传输到数据中心**外部或至少传输到运行Redis实例的物理计算机外部

如果您在仅启用AOF持久性的情况下运行Redis实例,您仍可以复制AOF以便创建备份。该文件可能没有最后一部分,但是Redis仍然可以加载它(请参阅前面有关AOF文件被截断的部分)。

灾难恢复

Redis上下文中的灾难恢复与备份基本相同,并且能够在许多不同的外部数据中心中传输这些备份。即使在某些灾难性事件影响Redis运行并生成其快照的主数据中心的情况下,也可以通过这种方式保护数据。

由于许多Redis用户都处于启动阶段,因此没有足够的钱可以花,我们将回顾成本不高的最有趣的灾难恢复技术。

  • Amazon S3和其他类似服务是实施灾难恢复系统的好方法。只需将您的每日或每小时RDB快照以加密形式传输到S3。您可以使用gpg -c(在对称加密模式下)加密数据。确保将密码存储在许多不同的安全位置(例如,将副本提供给组织中最重要的人员)。建议使用多个存储服务以提高数据安全性。
  • 使用SCP(SSH的一部分)将快照传输到远程服务器。这是一条相当简单和安全的方法:在离您很远的地方获得一个小型VPS,在该处安装ssh,然后生成不带密码的ssh客户端密钥,然后将其添加authorized_keys到您的小型VPS文件中。您已准备好以自动方式传输备份。在两个不同的提供商中获得至少两个VPS,以获得最佳结果。

重要的是要理解,如果未正确实施该系统,则很容易发生故障。至少要绝对确保在传输完成后,您能够验证文件大小(该大小应与您复制的文件之一匹配),如果使用的是VPS,也可以验证SHA1摘要。

如果由于某些原因无法传输新备份,则还需要某种独立的警报系统。


标题:redis从入门到实战(5)-redis数据持久化
作者:SmiteLi
地址:https://smite.site/articles/2019/10/22/1571725412117.html

评论

发表评论