Redis持久性文档中文翻译

本页提供了Redis持久性的技术描述,建议所有Redis用户阅读。为了更广泛地了解Redis持久性及其提供的持久性保证,您可能还想阅读Redis persistence demystified。

Redis持久性

Redis提供了一系列不同的持久性选项:
RDB持久性以指定的时间间隔执行数据集的时间点快照。
AOF持久性记录服务器接收到的每个写入操作,这些操作将在服务器启动时再次播放,重建原始数据集。命令的记录格式与Redis协议本身的格式相同,仅附加方式。Redis能够在日志太大时在后台重写它。
如果您想让数据在服务器运行期间一直存在,那么您可以完全禁用持久性。
可以在同一个实例中组合AOF和RDB。注意,在这种情况下,当Redis重新启动时,AOF文件将用于重建原始数据集,因为它保证是最完整的。
最重要的是要了解RDB和AOF持久性之间的不同权衡。让我们从RDB开始:

RDB优势

RDB是Redis数据的一个非常紧凑的单文件时间点表示。RDB文件非常适合备份。例如,您可能希望在最近24小时内每小时存档一次RDB文件,并在30天内每天保存一个RDB快照。这允许您在发生灾难时轻松恢复数据集的不同版本。
RDB非常适合灾难恢复,它是一个可以传输到远程数据中心或AmazonS3(可能是加密的)的压缩文件。
RDB使Redis的性能最大化,因为Redis父进程要持久化只需要派生一个子进程来完成其余的工作。父实例永远不会执行磁盘I/O或类似操作。
与AOF相比,RDB允许使用大数据集更快地重新启动。

RDB缺点

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

AOF优势

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

AOF缺点

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

 

好吧,那我该用什么呢?
一般的指示是,如果您希望与PostgreSQL提供的数据安全性相当,那么应该使用这两种持久性方法。
如果您非常关心自己的数据,但在发生灾难时仍然可以忍受几分钟的数据丢失,那么您可以简单地单独使用RDB。
有很多用户单独使用AOF,但是我们不鼓励这样做,因为时不时地使用RDB快照是进行数据库备份、更快地重新启动以及AOF引擎出现错误时的一个好主意。
注意:由于所有这些原因,我们将来很可能会将AOF和RDB统一到一个单一的持久性模型中(长期计划)。
下面几节将详细说明这两个持久性模型。


快照,

默认情况下,Redis将数据集的快照保存在磁盘上的一个名为转储.rdb. 如果数据集中至少有M个更改,可以将Redis配置为每隔N秒保存一次数据集,也可以手动调用SAVEBGSAVE命令。
例如,此配置将使Redis每60秒自动将数据集转储到磁盘,如果至少更改了1000个密钥:

save 60 1000

这种策略被称为快照。

工作原理

每当Redis需要将数据集转储到磁盘时,会发生以下情况:雷迪斯福克斯。我们现在有一个子进程和一个父进程。
子对象开始将数据集写入临时RDB文件。
当孩子写完新的RDB文件后,它将替换旧的RDB文件。
此方法允许Redis从“写时拷贝”语义中获益。

仅附加文件

快照不是很耐用。如果运行Redis的计算机停止运行,电源线出现故障,或者您不小心杀死了-9实例,则在Redis上写入的最新数据将丢失。虽然这对某些应用程序来说可能不是什么大问题,但也有一些完全持久性的用例,在这些情况下,Redis不是一个可行的选择。
对于Redis来说,append-only文件是另一种完全持久的策略。它在版本1.1中可用。
您可以在配置文件中打开AOF:

appendonly yes

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

日志重写

正如您所猜测的,随着写操作的执行,AOF变得越来越大。例如,如果您将一个计数器递增100倍,那么您将在数据集中得到一个包含最终值的键,但在AOF中只有100个条目。其中99个条目不需要重建当前状态。
因此Redis支持一个有趣的特性:它能够在后台重建AOF,而不会中断对客户端的服务。每当您发出BGREWRITEAOF Redis都会写入在内存中重建当前数据集所需的最短命令序列。如果您在Redis2.2中使用AOF,则需要不时运行BGREWRITEAOF。Redis 2.4能够自动触发日志重写(更多信息请参见2.4配置文件示例)。

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

您可以配置Redis在磁盘上同步数据的次数。有三种选择:
appendfsync always:每次向AOF追加新命令时都进行fsync。非常慢,非常安全。请注意,在执行来自多个客户机或管道的一批命令之后,这些命令被绑定到AOF,因此它意味着一次写入和一次fsync(在发送应答之前)。
appendfsync everysec:每秒fsync。足够快(在2.4中可能与快照一样快),如果发生灾难,您可能会丢失1秒的数据。
appendfsync no:从不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可能无法恢复,可能需要执行以下步骤:
备份你的文件。
使用redis附带的redis check aof工具修复原始文件:
$redis check aof—修复
或者使用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分叉,所以现在我们有一个子进程和一个父进程。
孩子开始在临时文件中写入新的AOF。
父级将所有新更改累积到内存缓冲区中(但同时它将新更改写入旧的append-only文件中,因此,如果重写失败,我们是安全的)。
当子进程完成对文件的重写后,父进程将获得一个信号,并在子进程生成的文件末尾追加内存缓冲区。
利润!现在Redis自动地将旧文件重命名为新文件,并开始向新文件追加新数据。

如何切换到AOF,如果我当前正在使用转储.rdb快照?
在Redis 2.0和Redis 2.2中有一个不同的过程来实现这一点,因为您可以猜到在Redis 2.2中它更简单,而且根本不需要重新启动。
Redis>=2.2
备份你最新的转储.rdb文件。
把这个备份转移到一个安全的地方。
发出以下两个命令:
redis cli config set appendonly是
redis cli配置集保存“”
请确保您的数据库包含与其包含的相同数量的键。
确保写入操作正确附加到仅附加文件。

第一个CONFIG命令启用仅附加文件。为了做到这一点,Redis将阻塞生成初始转储,然后将文件打开进行写入,并将开始追加所有下一个写查询。
第二个CONFIG命令用于关闭快照持久性。这是可选的,如果您希望可以同时启用这两个持久性方法。
重要提示:请记住编辑redis.conf版打开AOF,否则当您重新启动服务器时,配置更改将丢失,服务器将使用旧配置重新启动。


Redis 2.0

备份你最新的转储.rdb文件。
把这个备份转移到一个安全的地方。
停止对数据库的所有写入操作!
发出redis cli BGREWRITEAOF。这将创建只附加的文件。
当Redis完成生成AOF转储时停止服务器。
编辑redis.conf版end启用仅附加文件持久性。
重新启动服务器。
请确保您的数据库包含与其包含的相同数量的键。
确保写入操作正确附加到仅附加文件。

 

AOF与RDB持久性的交互作用
Redis>=2.4确保避免在RDB快照操作已在进行时触发AOF重写,或在AOF重写过程中允许BGSAVE。这可以防止两个Redis后台进程同时执行重磁盘I/O。
当快照正在进行中,并且用户使用BGREWRITEAOF显式请求日志重写操作时,服务器将以OK状态代码进行答复,告诉用户操作已被调度,并且一旦快照完成,重写将开始。
如果启用了AOF和RDB持久性,并且Redis重新启动,AOF文件将用于重建原始数据集,因为它保证是最完整的。

备份Redis数据

在开始本节之前,请务必阅读以下句子:确保备份数据库。磁盘损坏,云中的实例消失,等等:没有备份意味着数据消失在/dev/null中的巨大风险。
Redis非常适合数据备份,因为您可以在数据库运行时复制RDB文件:RDB一旦生成就永远不会被修改,而当它生成时,它使用一个临时名称,并且只有在新快照完成时才使用rename(2)原子性地重命名为其最终目的地。

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

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

如果运行只启用AOF持久性的Redis实例,仍然可以复制AOF以创建备份。文件可能缺少最后一部分,但Redis仍然可以加载它(请参阅前面关于截断的AOF文件的部分)。

灾难恢复

Redis环境下的灾难恢复与备份基本上是一样的,再加上能够在许多不同的外部数据中心传输这些备份。这样,即使在某些灾难性事件影响到Redis正在运行并生成快照的主数据中心的情况下,数据也是安全的。
由于许多Redis用户都处于初创阶段,因此没有足够的资金来花费,我们将回顾一下那些成本不太高的最有趣的灾难恢复技术。

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

重要的是要明白,如果不以正确的方式实现,这个系统很容易失败。至少要确保传输完成后,您能够验证文件大小(应该与您复制的文件相匹配),如果您使用的是VPS,还可以验证SHA1摘要。
如果由于某种原因新备份的传输不起作用,您还需要某种独立的警报系统。

 

posted @ 2020-12-11 16:37  Suixin随心  阅读(151)  评论(0编辑  收藏  举报