Redis的持久化

什么是Redis的持久化?

  RDB(Redis DataBase) 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
  AOF(Append Only File) 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
  Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
  甚至可以关闭持久化功能,让数据只在服务器运行时存在。
了解 RDB 持久化和 AOF 持久化之间的异同是非常重要的, 以下几个小节将详细地介绍这这两种持久化功能, 并对它们的相同和不同之处进行说明。

RDB

RDB的优点

  1. RDB 非常适用于灾难恢复(disaster recovery)
  2. 2.RDB 可以最大化 Redis 的性能
  3. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

RDB的缺点

  1. 对数据完整性和一致性要求不高
  2. 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改
  3. fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
    在数据集比较庞大时, fork()可能会非常耗时,造成服务器在某某毫秒内停止处理客户端

RDB快照

  默认情况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。
  但是可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:

save60 100

  也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 立即进行数据集保存操作。而不去理会设置的自动备份,但save的时候只管保存,其他全部阻塞,bgsave 是在后台异步进行快照,同时还可以进行用户的请求,lastsave 获取最后一次快照的时间
  
快照的运行方式

  当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  1. Redis 调用 fork() ,同时拥有父进程和子进程。
  2. 子进程将数据集写入到一个临时 RDB 文件中。
  3. 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

AOF

AOF的优点

  1. AOF 文件是一个只进行追加操作的日志文件(append only log),即使某些原因包含了未写入完整的命令,redis-check-aof 工具也可以轻易地修复这种问题。
  2. 使用 AOF 持久化会让 Redis 变得非常耐久(much more durable),可以设置不同的 fsync 策略,AOF 的默认策略为每秒钟 fsync 一次,就算发生故障也只会丢失一秒的数据。
  3. Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写。
  4. AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。

AOF的缺点

  1. 相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdbaof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。
  2. AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。

appeng-only file

  如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。为解决这个问题,你可以通过修改配置文件来打开 AOF 功能:

appendonly yes

  打开AOF功能时,每当 Redis 执行一个写的命令时, 这个命令就会被追加到 AOF 文件的末尾。当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
  
AOF重写

  因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。但是Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。这很完美的解决了AOF文件体积的问题。执行 下面命令

BGREWRITEAOF

  Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。
  
AOF的同步策略

  通过配置 Redis 多久才将数据 fsync 到磁盘一次。有三个选项:
  always:每次有新命令追加到 AOF 文件时就执行一次 fsync 。非常慢,也非常安全。
  everysec:每秒 fsync 一次。足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
  no:从不 fsync 。将数据交给操作系统来处理。更快,也更不安全的选择。
  
  推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

因意外导致AOF文件出错,怎么进行修复?

  Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:

  1. 为现有的 AOF 文件创建一个备份。
  2. 使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复。
redis-check-aof --fix

  3. (可选)使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处。
  4. 重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。

AOF的运作方式

  AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制。
以下是 AOF 重写的执行步骤:
  1. Redis 执行 fork() ,现在同时拥有父进程和子进程。
  2. 子进程开始将新 AOF 文件的内容写入到临时文件。
  3. 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾: 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
  4. 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
  5. 搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
  
怎么从RDB持久化切换到AOF持久化

  在 Redis 2.2 或以上版本,可以在不重启的情况下,从 RDB 切换到 AOF :
  1. 为最新的 dump.rdb 文件创建一个备份。
  2. 将备份放到一个安全的地方。
  3. 执行以下两条命令:
 

redis-cli> config set appendonly yes
redis-cli> config set save ""

  4. 确保命令执行之后,数据库的键的数量没有改变。
  5. 确保写命令会被正确地追加到 AOF 文件的末尾。
  
  注:
  第一条命令开启了 AOF 功能: Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾。
  第二条命令用于关闭 RDB 功能。 这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能。
  
  别忘了在 redis.conf 中打开 AOF 功能! 否则, 服务器重启之后, 之前通过 CONFIGSET 设置的配置就会被遗忘, 程序仍然按原来的配置来启动服务器。

备份Redis数据库

  请将下面这句话铭记于心: 一定要备份你的数据库!一定要备份你的数据库!一定要备份你的数据库!重要的是说三遍
  
  磁盘故障, 节点失效, 诸如此类的问题都可能让你的数据消失不见, 不进行备份你会哭的。
  Redis 对于数据备份做的非常友好, 因为你可以在服务器运行的时候对 RDB 文件进行复制。当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用rename(2) 原子地用临时文件替换原来的 RDB 文件。
  
以下是官网给的一些建议:

  创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
  确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
  至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
  
性能建议

  因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
  
  如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
  
  如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值