分享

Redis 3.0中文官方文档翻译计划(10) ——持久化

旧收音机 发表于 2015-4-12 17:26:48 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 3 15968
本帖最后由 旧收音机 于 2015-4-25 17:43 编辑

问题导读
1、Redis怎么来持久化?
2、RDB有哪些优点和缺点?
3、AOF有哪些优点和缺点?
4、RDB和AOF改如何选择呢?
5、快照是什么?
6、Redis持久化是怎么工作的?
7、AOF持久性如何?
8、AOF损坏了怎么办?
9、如何从RDB切换到AOF?
10、AOF和RDB的相互作用?
11、怎么去处理备份数据和灾难恢复?










本文提供对Redis持久化(persistence)的技术性描述,适合所有的Redis用户来阅读。想获得对Redis持久化和持久性保证有更全面的了解,也可以读一下作者的博客文章(地址为http://antirez.com/post/redis-persistence-demystified.html,译者注)。

    Redis持久化(Persistence)
    Redis提供了不同持久化范围的选项:
  • RDB持久化以指定的时间间隔执行数据集的即时点(point-in-time)快照。
  • AOF持久化在服务端记录每次收到的写操作,在服务器启动时会重放,以重建原始数据集。命令使用和Redis协议一样的格式以追加的方式来记录。当文件太大时Redis会在后台重写日志。
  • 如果你愿意,你可以完全禁止持久化,如果你只是希望你的数据在服务器运行期间才存在的话。
  • 可以在同一个实例上同时支持AOF和RDB。注意,在这种情况下,当Redis重启时,AOF文件会被用于重建原始数据集,因为它被保证是最完整的数据。

    理解RDB和AOF持久化之间的各自优劣(trade-offs)是一件非常重要的事情。让我们先从RDB开始:

   RDB优点(RDB advantages)
  • RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
  • RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心,或者是Amazon S3(可能得加密)。
  • RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
  • RDB在重启保存了大数据集的实例时比AOF要快。


    RDB缺点(RDB disadvantages)
    当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
    RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。

    AOF优点(AOF advantages)
  • 使用AOF Redis会更具有可持久性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
  • AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。
  • 当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
  • AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。


    AOF缺点(AOF disadvantages)
  • 对同样的数据集,AOF文件通常要大于等价的RDB文件。
  • AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。
  • 在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。但是,1)要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据)对bug的免疫力更强。2)我们还没有收到一份用户在真实世界中检测到崩溃的报告。


    我们该选谁(what)
    通常来说,你应该同时使用这两种持久化方法,以达到和PostgreSQL提供的一样的数据安全程度。
    如果你很关注你的数据,但是仍然可以接受灾难时有几分钟的数据丢失,你可以只单独使用RDB。
    有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。
    注意:基于这些原因,将来我们可能会统一AOF和RDB为一种单一的持久化模型(长远计划)。
    下面的部分将介绍两种持久化模型等多的细节。

    快照(Snapshotting)
    默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。
    例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
  1. save 60 1000
复制代码




    这种策略被称为快照。

    如何工作(How works)
    每当Redis需要转储数据集到磁盘时,会发生:
  • Redis调用fork()。于是我们有了父子两个进程。
  • 子进程开始将数据集写入一个临时RDB文件。
  • 当子进程完成了新RDB文件,替换掉旧文件。

    这个方法可以让Redis获益于写时复制(copy-on-write)机制。

   只追加文件(Append-only file)
    快照并不是非常具有可持久性(durable)。如果你运行Redis的电脑停机了,电源线断了,或者你不小心kill -9掉你的实例,最近写入Redis的数据将会丢失。尽管这个对一些应用程序来说不是什么大事,但是也有一些需要完全可持久性(durability)的场景,在这些场景下可能就不合适了。
    只追加文件是一个替代方案,是Redis的完全可持久性策略。在1.1版本中就可用了。
    你可以在你的配置文件中开启AOF:
  1. appendonly yes
复制代码
从现在开始,每次Redis收到修改数据集的命令,将会被追加到AOF中。当你重启Redis的时候,就会重放(re-play)AOF文件来重建状态。

    日志重写(Log rewriting)
    你可以猜得到,写操作不断执行的时候AOF文件会越来越大。例如,如果你增加一个计数器100次,你的数据集里只会有一个键存储这最终值,但是却有100条记录在AOF中。其中99条记录在重建当前状态时是不需要的。
    于是Redis支持一个有趣的特性:在后台重建AOF而不影响服务客户端。每当你发送BGREWRITEAOF时,Redis将会写入一个新的AOF文件,包含重建当前内存中数据集所需的最短命令序列。如果你使用的是Redis 2.2的AOF,你需要不时的运行BGREWRITEAOF命令。Redis 2.4可以自动触发日志重写(查看Redis 2.4中的示例配置文件以获得更多信息)。

    AOF持久性如何(How durable)
    你可以配置多久Redis会fsync数据到磁盘一次。有三个选项:
  • 每次一个新命令追加到AOF文件中时执行fsync。非常非常慢,但是非常安全。
  • 每秒执行fsync。够快(2.4版本中差不多和快照一样快),但是当灾难来临时会丢失1秒的数据。
  • 从不执行fsync,直接将你的数据交到操作系统手里。更快,但是更不安全。

    建议的(也是默认的)策略是每秒执行一次fsync。既快,也相当安全。一直执行的策略在实践中非常慢(尽管在Redis 2.0中有所改进),因为没法让fsync这个操作本身更快。

    AOF损坏了怎么办(corrupted)
    有可能在写AOF文件时服务器崩溃(crash),文件损坏后Redis就无法装载了。如果这个发生的话,你可以使用下面的步骤来解决这个问题:
  • 创建AOF的一个拷贝用于备份。
  • 使用Redis自带的redis-check-aof工具来修复原文件:
  • $ redis-check-aof --fix
  • 使用diff -u来检查两个文件有什么不同。
  • 用修复好的文件来重启服务器。


    如何工作(How works)
    日志重写采用了和快照一样的写时复制机制。下面是过程:
  • Redis调用fork()。于是我们有了父子两个进程。
  • 子进程开始向一个临时文件中写AOF。
  • 父进程在一个内存缓冲区中积累新的变更(同时将新的变更写入旧的AOF文件,所以即使重写失败我们也安全)。
  • 当子进程完成重写文件,父进程收到一个信号,追加内存缓冲区到子进程创建的文件末尾。
  • 搞定!现在Redis自动重命名旧文件为新的,然后开始追加新数据到新文件。


    如何从RDB切换到AOF(How switch)
    在Redis 2.2及以上版本中非常简单,也不需要重启。
  • 备份你最新的dump.rdb文件。
  • 把备份文件放到一个安全的地方。
  • 发送以下两个命令:
  • redis-cli config set appendonly yes
  • redis-cli config set save ""
  • 确保你的数据库含有其包含的相同的键的数量。
  • 确保写被正确的追加到AOF文件。

    第一个CONFIG命令开启AOF。Redis会阻塞以生成初始转储文件,然后打开文件准备写,开始追加写操作。
    第二个CONFIG命令用于关闭快照持久化。这一步是可选的,如果你想同时开启这两种持久化方法。
    重要:记得编辑你的redis.conf文件来开启AOF,否则当你重启服务器时,你的配置修改将会丢失,服务器又会使用旧的配置。

    此处省略一万字。。。。。。原文此处介绍2.0老版本怎么操作。

    AOF和RDB的相互作用(Interactions)
    Redis 2.4及以后的版本中,不允许在RDB快照操作运行过程中触发AOF重写,也不允许在AOF重写运行过程中运行BGSAVE。这防止了两个Redis后台进程同时对磁盘进行繁重的IO操作。
    当在快照运行的过程中,用户使用BGREWRITEAOF显式请求日志重写操作的话,服务器会答复一个OK状态码,告诉用户这个操作已经被安排调度,等到快照完成时开始重写。
    Redis在同时开启AOF和RDB的情况下重启,会使用AOF文件来重建原始数据集,因为通常AOF文件是保存数据最完整的。

    备份数据(Backing up)
    开始这一部分之前,请务必牢记:一定要备份你的数据库。磁盘损坏,云中实例丢失,等等:没有备份意味着数据丢失的巨大风险。
    Redis对数据备份非常友好,因为你可以在数据库运行时拷贝RDB文件:RDB文件一旦生成就不会被修改,文件生成到一个临时文件中,当新的快照完成后,将自动使用rename(2)原子性的修改文件名为目标文件。
    这意味着,在服务器运行时拷贝RDB文件是完全安全的。以下是我们的建议:
  • 创建一个定时任务(cron job),每隔一个小时创建一个RDB快照到一个目录,每天的快照放在另外一个目录。
  • 每次定时脚本运行时,务必使用find命令来删除旧的快照:例如,你可以保存最近48小时内的每小时快照,一到两个月的内的每天快照。注意命名快照时加上日期时间信息。
  • 至少每天一次将你的RDB快照传输到你的数据中心之外,或者至少传输到运行你的Redis实例的物理机之外。


    灾难恢复(Disaster recovery)
    在Redis中灾难恢复基本上就是指备份,以及将这些备份传输到外部的多个数据中心。这样即使一些灾难性的事件影响到运行Redis和生成快照的主数据中心,数据也是安全的。
    由于许多Redis用户都是启动阶段的屌丝,没有太多钱花,我们会介绍一些最有意思的灾难恢复技术,而不用太多的花销。
  • Amazon S3和一些类似的服务是帮助你灾难恢复系统的一个好办法。只需要将你的每日或每小时的RDB快照以加密的方式传输到S3.你可以使用gpg -c来加密你的数据(以对称加密模式)。确保将你的密码保存在不同的安全地方(例如给一份到你的组织中的最重要的人)。推荐使用多个存储服务来改进数据安全。
  • 使用SCP(SSH的组成部分)来传输你的快照到远程服务器。这是一种相当简单和安全的方式:在远离你的位置搞一个小的VPS,安装ssh,生成一个无口令的ssh客户端key,并将其添加到你的VPS上的authorized_keys文件中。你就可以自动的传输备份文件了。为了达到好的效果,最好是至少从不同的提供商那搞两个VPS。

    要知道这种系统如果没有正确的处理会很容易失败。至少一定要确保传输完成后验证文件的大小(要匹配你拷贝的文件),如果你使用VPS的话,可以使用SHA1摘要。
    你还需要一个某种独立的告警系统,在某些原因导致的传输备份过程不正常时告警。




相关内容:
            Redis 3.0官方文档翻译计划(1)  ——Redis介绍

             Redis 3.0官方文档翻译计划(2) ——从入门到精通(上)

             Redis 3.0官方文档翻译计划(3) ——从入门到精通(中)

            Redis 3.0官方文档翻译计划(4) ——从入门到精通(下)

           Redis 3.0中文官方文档翻译计划(5) ——使用Redis实现Twitter(上)

            Redis 3.0中文官方文档翻译计划(6) ——使用Redis实现Twitter(下)

          Redis 3.0中文官方文档翻译计划(7) ——使用Redis作为LRU缓存

            Redis 3.0中文官方文档翻译计划(8) ——分片

           Redis 3.0中文官方文档翻译计划(9) ——复制

          Redis 3.0中文官方文档翻译计划(10) ——持久化

          Redis 3.0中文官方文档翻译计划(11) ——集中插入

           Redis 3.0中文官方文档翻译计划(12) ——高可用(上)

          Redis 3.0中文官方文档翻译计划(13) ——高可用(下)

          Redis 3.0中文官方文档翻译计划(14) ——高可用客户端指引

          Redis 3.0中文官方文档翻译计划(15) ——集群(上)
          Redis 3.0中文官方文档翻译计划(16) ——集群(中)

          Redis 3.0中文官方文档翻译计划(17) ——集群(下)

已有(3)人评论

跳转到指定楼层
QQo0oBIQ 发表于 2015-4-13 09:09:42
回复

使用道具 举报

hb1984 发表于 2015-4-13 17:54:20
谢谢楼主分享。     
回复

使用道具 举报

hb1984 发表于 2015-4-13 17:58:48
谢谢楼主分享。            
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条