redis的学习(四)redis持久化方式

Redis提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF。
RDB持久化可以在指定的时间间隔内生成数据集的时间点快照。

AOF持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
AOF文件中的命令全部以Redis协议的格式来保存,新命令会被追加到文件末尾。Redis还可以在后台对AOF文件进行重写,使得AOF文件的体积不会超出保存数据集状态所需的实际大小。

Redis还可以同时使用AOF持久化和RDB持久化。在这种情况下,当Redis重启时,它会有限使用AOF文件来还原数据集,因为AOF文件保存的数据集通常比RDB所保存的数据集更完整。你甚至可以关闭持久化功能,让数据只在服务器运行时存在。

RDB持久化

RDB快照:
在默认的情况下,Redis将数据集快照保存在名字为dump.rdb的二进制文件中。你可以对Redis进行设置,让他在“N秒内数据集至少有M个改动”这一条件被满足时,自动保存一次数据集。你也可以通过调用SAVE或者BGSAVE,手动让Redis进行数据集保存操作。
这种持久化方式被称为快照。

快照的运作方式:
当Redis需要保存dump.rdb文件时,服务器执行以下操作:
Redis调用fork()创建一个子进程。
子进程将数据集写入到一个临时RDB文件中。
当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的RDB文件,并删除旧的RDB文件。

RDB的优点:
RDB是一个非常紧凑的文件,它保存了Redis在某个时间点上的数据集。这种文件非常适合用于备份;比如说,你可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB非常适用于灾难恢复;它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心。RDB可以最大化Redis的性能:父进程无须执行任何磁盘I/O操作。RDB在恢复大数据集时比AOF的恢复速度要快。

RDB的缺点:
如果要尽量避免在服务器故障时丢失数据,那么RDB不适合你。虽然Redis允许你设置不同的保存点来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此你可能至少5分钟才保存一次RDB文件。在这种情况下,一旦发生故障机,你就可能丢失好几分钟数据。每次保存RDB的时候,Redis都要fork()出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时,fork()可能会非常耗时,造成服务器在某某毫秒内停止处理客户端;如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。虽然AOF重写也需要进行fork(),但无论AOF重写的执行间隔有多长,数据的耐久性都不会有任何损失。

AOF持久化

AOF运作方式和重写机制:
AOF的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加,AOF文件的体积也会变得越来越大。举个例子,如果你对一个计数器调用了100次INCR,那么仅仅是为了保存这个计数器的当前值,AOF文件就需要使用100条记录。然而在实际上,只使用一条SET命令已经足以保存计数器的当前值了,其余99条记录实际上都是多余的。为了处理这种情况,Redis支持一种有趣的特性:可以在不打断服务客户端的情况下,对AOF文件进行重建。执行BGREWRITEAOF命令,Redis将生成新的AOF文件,这个文件包含重建当前数据集所需的最少命令。

AOF配置:
Redis是默认关闭AOF持久化模式的,我们可以在Redis配置文件中开启AOF持久化。

开启AOF持久化:
appendonly yes(默认为no,关闭)

AOF持久化配置文件的名称:
appendfilename “appendonly.aof”

AOF持久化策略:
appendfsync always(每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。)
appendfsync everysec(每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。)
appendfsync no(将数据交给操作系统来处理。更快,也更不安全的选择)

AOF的优点:
AOF持久化会让Redis变得非常耐久:你可以设置不同的fsync策略,比如无fsync,每秒钟一次fsync,或每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,Redis任然可以保持良好的性能,并且就算发生故障停机,也只会丢失一秒钟的数据(fsync会在后台线程执行,所以主线程可以继续处理命令请求)。AOF文件只是一个只追加操作的日志文件,因此对AOF文件的写入不需要进行seek,即使日志文件因为某些原因而包含了未写入完整的命令(比如写入磁盘已满,写入中途宕机等等),redis-check-aof工具也可以轻易地修复这种问题。Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写:重写后的新AOF文件包含了恢复当前数据集所需要的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的AOF文件中,即使重写的过程中发生意外,现有的AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。AOF文件有序地保存了对数据集执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析也很轻松。导出AOF文件也非常简单:举个例子,如果你不小心执行了FlushAll命令,但只要AOF文件未被重写,那么只要停止服务器,移除AOF文件末尾的FlushAll命令,并重启Redis,就可以将数据集恢复到FlushAll之前的状态。

AOF的缺点:
对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积。根据所使用的fsync策略,AOF的速度可能会慢于RDB。在一半情况下,每秒fsync的性能依然非常高,而关闭fsync可以让AOF速度和RDB一样快,即使在高负荷下也是如此。不过在处理巨大的写入载入时,RDB可以提供更有保证的最大延迟时间。AOF在过去曾经发生过这样的bug:因为个别命令原因,导致AOF文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。

RDB和AOF的选择

一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。因为以上提到的种种原因, 未来可能会将 AOF 和 RDB 整合成单个持久化模型。

原文地址:https://www.cnblogs.com/cqy1026/p/13892661.html