Redis 的 RDB&AOF 理解。

sddtc 于 2016-11-17 发布

Redis Persistence

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

最重要的是要理解RDB和AOF持久性之间的不同取舍。 让我们从RDB开始:
RDB的优点
RDB是您的Redis数据的非常紧凑的单文件时间点表示。RDB文件是完美的备份。 例如,您可能希望在最近24小时内每小时归档RDB文件,并且每天保存RDB快照30天。 这允许您在灾难发生时轻松恢复数据集的不同版本。
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能够在后台自动重写AOF,当它变得太大时。重写是完全安全的,因为当Redis继续追加到旧的文件,一个全新的,产生与创建当前数据集所需的最少的操作集,一旦第二个文件就绪,Redis切换两个并开始追加新的那一个。
AOF包含一个以易于理解和解析格式一个接一个的所有操作的日志。您甚至可以轻松导出AOF文件。例如,即使您使用FLUSHALL命令刷新了所有错误,如果在此期间没有执行日志重写,您仍然可以保存您的数据集,只是停止服务器,删除最新的命令,并重新启动Redis。

AOF的缺点
AOF文件通常大于同一数据集的等效RDB文件。
根据确切的fsync策略,AOF可能比RDB慢。一般来说,fsync设置为每秒的性能仍然非常高,并且fsync禁用,它应该与RDB一样快,即使在高负载下。仍然RDB能够提供关于最大延迟的更多保证,即使在巨大的写入负载的情况下。
在过去,我们遇到了特定命令中的罕见错误(例如,有一个涉及阻塞命令,如BRPOPLPUSH)导致产生的AOF在重新加载时不能完全重现相同的数据集。这个bug很少,我们在测试套件中进行测试,自动创建随机复杂数据集,并重新加载它们以检查一切是否正确,但是这种错误几乎不属于RDB持久性。为了使这一点更加清楚:Redis AOF工作逐步更新现有状态,如MySQL或MongoDB,而RDB快照从头开始创建一切从头开始,这在概念上更强大。然而,应该注意的是,每当AOF被Redis重写时,从包含在数据集中的实际数据开始重新创建AOF,与总是附加AOF文件(或一个重写的读取)相比,旧的AOF而不是读取存储器中的数据)。 2)我们从来没有一个单一的报告,从用户的AOF毁坏在现实世界中检测到。

好吧,我应该使用什么
一般的指示是,如果你想要一定程度的数据安全性就像PostgreSQL可以提供给你的,你应该使用两种持久性方法。
如果你关心你的数据,但仍然可以忍受在几分钟的数据丢失的情况下的灾难,你可以只使用RDB单独。
有很多用户单独使用AOF,但我们不鼓励它,因为有时有一个RDB快照是一个伟大的想法做数据库备份,更快的重新启动,以及在AOF引擎中的错误的情况下。
注意:由于所有这些原因,我们可能最终将AOF和RDB统一为单一的持久性模型在未来(长期计划)。 以下部分将说明有关两个持久性模型的更多详细信息。

快照
默认情况下,Redis将数据集的快照保存在磁盘上的二进制文件dump.rdb中。如果数据集中至少有M个更改,您可以配置Redis使其每N秒保存数据集,也可以手动调用SAVE或BGSAVE命令。
例如,如果至少1000个键已更改,此配置将使Redis每60秒自动将数据集转储到磁盘:
SAVE 60 1000
这种策略称为快照。

怎么运行的
每当Redis需要将数据集转储到磁盘时,会发生以下情况:
Redis fork()。我们现在有一个子进程和一个父进程。
子开始将数据集写入临时RDB文件。
当子进程写入新的RDB文件时,它将替换旧的RDB文件。
此方法允许Redis受益于写时复制语义。

仅附加文件
快照不是很耐用。如果你的计算机运行Redis停止,你的电源线失败,或者你不小心杀了-9你的实例,写在Redis上的最新数据将丢失。虽然这对于某些应用程序可能不是什么大不了的,但有一些用例可以提供完全的持久​​性,在这些情况下,Redis不是一个可行的选择。
附加文件是Redis的替代,完全持久的策略。它在1.1版本中可用。
您可以在配置文件中打开AOF:
appendonly yes
从现在开始,每次Redis接收到更改数据集的命令(例如SET)时,它会将其附加到AOF。当您重新启动Redis时,它将重新播放AOF以重建状态。

日志重写
正如你可以猜到的,AOF随着写操作的执行而变得越来越大。例如,如果您将计数器增加100次,则最终将在数据集中包含最终值的单个键,但在AOF中有100个条目。这些条目中的99个不需要重建当前状态。 所以Redis支持一个有趣的功能:它能够在后台重建AOF而不中断对客户端的服务。每当您发出BGREWRITEAOF时,Redis将写入在内存中重建当前数据集所需的最短命令序列。
如果你使用带有Redis 2.2的AOF,你需要不时运行BGREWRITEAOF。Redis 2.4能够自动触发日志重写(有关详细信息,请参阅2.4示例配置文件)。

附加文件有多耐久? 您可以配置Redis将fsync磁盘上的数据的次数。有三个选项:
fsync每次将新命令附加到AOF。非常非常缓慢,非常安全。
fsync每秒。足够快(在2.4可能与快照一样快),如果有灾难,你可以失去1秒的数据。
从不fsync,只是把你的数据在操作系统的手中。更快,更安全的方法。
建议(和默认)策略是每秒fsync。它是非常快,很安全。总是策略在实践中很慢(虽然在Redis 2.0中有所改进) - 没有办法使fsync比它快。

如果我的AOF被损坏,我该怎么办?
有可能服务器在写入AOF文件时崩溃(这仍然不应该导致不一致),以Redis不再可加载的方式破坏文件。发生这种情况时,您可以使用以下过程解决此问题:
制作AOF文件的备份副本。
使用Redis附带的redis-check-aof工具修复原始文件:
$ redis-check-aof –fix
(可选)使用diff -u来检查两个文件之间的区别。
使用固定文件重新启动服务器。

怎么运行的 日志重写使用已经用于快照的相同的写时复制技巧。这是它的工作原理:
Redis fork,所以现在我们有一个子进程和一个父进程。
子进程开始在一个临时文件中写新的AOF。
父存储器在内存缓冲区中累积所有新的更改(但是同时它将新的更改写入旧的仅附加文件中,因此,如果重写失败,我们是安全的)。
当子进程重写文件时,父进程获取信号,并将内存缓冲区附加到子进程生成的文件的末尾。
profit!现在Redis以原子方式将旧文件重命名为新文件,并开始将新数据附加到新文件中。

如果我目前使用dump.rdb快照,如何切换到AOF?
在Redis 2.0和Redis 2.2中有一个不同的程序,你可以猜测它在Redis 2.2中更简单,并且不需要重新启动。
Redis> = 2.2
备份最新的dump.rdb文件。将此备份传输到安全的地方。
发出以下两个命令:
redis-cli config set appendonly yes
redis-cli config set save“”
请确保您的数据库包含相同数量的键。
确保写入正确地附加到append only文件。
第一个CONFIG命令启用仅附加文件。为了做到这一点,Redis将阻塞生成初始转储,然后将打开该文件进行写入,并将开始附加所有下一个写入查询。
第二个CONFIG命令用于关闭快照持久性。这是可选的,如果您希望您可以同时启用持久性方法。
重要信息:记住编辑您的redis.conf以打开AOF,否则当您重新启动服务器时,配置更改将丢失,服务器将再次使用旧配置启动。

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

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实例的物理机器外部传输。 灾难恢复
在Redis的上下文中的灾难恢复与备份基本上是一样的,加上在许多不同的外部数据中心中传输这些备份的能力。这样,即使在一些灾难性事件影响Redis运行并生成其快照的主数据中心的情况下,数据也是安全的。
由于许多Redis用户处于启动环境中,因此没有足够的资金支出,我们将审查最有趣的灾难恢复技术,这些技术不会有太高的成本。
Amazon S3和其他类似的服务是安装灾难恢复系统的好方法。只需以加密形式将每天或每小时的RDB快照传输到S3。您可以使用gpg -c(对称加密模式)加密数据。确保将密码存储在许多不同的安全位置(例如向您组织中最重要的人员提供副本)。建议使用多个存储服务以提高数据安全性。
使用SCP(SSH的一部分)将远程传送到远端服务器。这是一个相当简单和安全的路由:在离你很远的地方获得一个小型VPS,在那里安装ssh,生成没有passphrase的ssh客户端密钥,然后将其添加到小型VPS的authorized_keys文件中。您已准备好以自动方式传输备份。在两个不同的提供商获得至少两个VPS以获得最佳结果。
重要的是要理解,如果没有以正确的方式编码,这个系统可能容易失败。至少确保在传输完成后,您可以验证文件大小(应该匹配您复制的文件之一),如果您使用VPS,则可能还有SHA1摘要。
如果新备份的传输由于某种原因不起作用,您还需要某种独立的警报系统。