[不忘初心]
在Redis的命令中还有关于服务器的命令我们未做介绍,是由于其中的部分命令涉及持久化,集群等方面的内容。因此,本文我们就先来看看持久化部分的内容。好了,废话不表,马上开始我们的正文部分吧!
-------------------------------------------------------------------------------------------------------------------------------------
前言
本文提供关于Redis持久化的技术性描述,推荐所有Redis的用户都阅读。如果想更加广泛的了解Redis持久化和持久化所保证的耐久度,推荐阅读Redis的这篇介绍『http://oldblog.antirez.com/post/redis-persistence-demystified.html』
Redis持久化
- Redis提供了不同级别的持久化选项:
- RDB持久化可以在指定的时间间隔内生成数据集的时间点快照。
- AOF持久化记录了服务器所执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的所有命令全部以Redis协议的格式来保存,新命令会被追加到文件的末尾。Redis还可以在后台对AOF文件进行重写,使得AOF文件的体积不会超过数据集状态所需的实际大小。
- 如果愿意的话,完全可以禁用持久化,使得数据只在服务器运行时存在。
- Redis还可以同时使用AOF和RDB。在这种情况下,Redis重新启动时会使用AOF文件来恢复数据集,因为其能够保证最完整的数据
RDB的优点:
- RDB是一个非常进行的单文件,它保存了Redis某个时间点上数据集。RDB文件是非常适用于备份的。举个例子:你可以在最近的24小时内,每个小时进行一个备份,并且在每个月的每一天也进行一次备份。这种做法允许在发生问题的情况下,轻松地将数据集恢复到不同的版本上。
- RDB非常适用于灾难恢复,它只有一个非常紧凑的文件,可以被传送到别的数据中心,或者亚马逊S3中。
- RDB可以最大化Redis的性能,父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存的工作,父进程将不再操作磁盘的I/O操作。
- RDB在回复大数据集时的速度要比AOF的回复速度要快。
RDB的缺点:
- 如果需要尽量避免在服务器故障时丢失数据,那么RDB不是一个好的选择。虽然你可以配置不同的保存点来控制RDB文件生成频率。但是因为RDB文件需要保存整个数据集的状态,所以这并不是一个非常轻松的操作。因此,你可能至少5分钟才会进行一个保存操作【具体配置方法我们后续介绍】,在这种情况下,Redis发生故障停机是,你可能会丢失最近几分钟内的所有数据。
- RDB需要在每次持久化是都要fork()出一个子进程,并且由子进程来完成持久化工作,当数据集非常大,或者CPU性能不足时,fork操作可能会非常耗时,甚至会造成Redis服务器在数毫秒乃至1秒钟内停止响应客户端的请求。虽然AOF也需要fork但是无论AOF重写的执行间隔有多么的长,数据的持久化都不会有任何的损失。
AOF的优点:
- 使用AOF持久化将会使得Redis变得十分耐久:你可以设置不同的fsync策略:no fsync,fsync every second,fsync at every query。默认情况下的策略为fsync every second,在这种配置下,Redis仍然能够保持良好的性能,即便是发生故障,最所也只是丢失1秒钟的数据。(fsync会在后台进程中执行,所以主线程可以尽可能的处理命令)
- AOF文件是一个只进行追加操作的日志文件,因此,对文件写入不需要进行seek操作,即使日志因为某些原因(如,磁盘已满,中途停机等)没有写入完整的命令,redis-check-aof工具也能够轻松的修复这种问题。
- Reids可以在AOF文件体积过大时,自动的在后台对AOF我呢见进行重写,重写后的新AOF文件包含了回复当前数据集所需的最小命令集合。整个重写的过程是绝对安全的,因为Redis在创建新的AOF文件时,仍然会继续将命令追加到现有的AOF文件里面,即使整个重写过程中发生付账,也不会导致现有的AOF文件丢失。并且,当新的AOF文件创建完成时,Redis就会用新的AOF文件来取代旧的文件,追加操作也会切换到新的AOF文件上。
- AOF文件有序的保存了对数据库执行的所有操作,这些操作以Redis协议的格式进行保存,因此,AOF文件的内容非常的容易被理解与分析。导出文件也十分轻松。举个例子,如果不小心执行了FLUSHALL命令,但是只要AOF文件没有被重写,那么停止服务器,除去AOF文件末尾的FLUSHALL命令,并且重新启动Redis,就可以恢复到FLUSHALL执行之前的状态了。
AOF的缺点:
- 对于相同的数据集,AOF文件的体积通常大于RDB文件的体积。
- 根据fsync的策略不同,AOF的速度可能会慢于RDB。在一般情况下,fsync every second 的性能仍然非常的高。而关闭fsync可以让AOF与RDB的速度一样快,即使在高负荷之下也是如此。不过在处理巨大的写载入时,RDB可以提供更加有保证的最大延迟。
- 在过去的一段时间,AOF出现了在特殊命令下的BUG(如阻塞命令BRPOPLPSH):导致了AOF文件在重新载入时,无法将数据集恢复成保存时的模样。这样的BUG是非常少见的,并且测试套件里针对这种情况添加了测试,自动生成随机的复杂数据集,并通过重新载入这些数据来保证一切正常。但是类似BUG在RDB中几乎是不可能出现的。为了更加清楚的了解这点:Redis AOF的自动增量式的更新现有的状态,如Mysql,MongoDB那样,然而,RDB快照一次又一次的从头开始创建所有,在概念上更加的健壮与稳定。
- 然而这里还有一些事情需要关注:
- 每次AOF被Redis重写是从包含实际数据的数据集中从头开始创建的,使得BUG更加的容易出现,相比于一直对一个文件进行追加操作。(或者一个重写操作读取的是旧的AOF文件代替从内存中读取数据)
- 迄今为止,我们实际中还没有收到用户关于AOF错误问题的单一报告。
- 一般情况下的建议是,如果想要达到PostgreSQL提供的数据分级安全,那么就需要同时使用AOF与RDB两种持久化策略。
- 如果你非常关心你的数据,但是仍然能够接受发生错误时,数分钟内的数据丢失,那么你可以只简单的使用RDB策略。
- 有很多用户只是用AOF策略。但是我们比推荐这中做法。因为定期的生成快照非常便于进行数据库备份。并且RDB备份的重载速度也优于AOF,除此之外,还能够避免之前问题所出现的提到的BUG。
- 注:对于上面我们提到的种种原因,未来我们会将AOF与RDB整合成为一个单一的持久化模型。(这是一个长期计划)
RDB快照:
save 60 1000这种保存策略我们就称为快照。
- Redis调用fork(),同时拥有父进程,子进程。
- 子进程将数据库写入到一个临时的RDB文件中。
- 当子进程完成对RDB文件写操作时,用这个文件替换掉原来的RDB文件。
appendonly yes配置之后,重新启动Redis并加载配置文件,每当Redis执行了一个改变数据集中的数据的命令是,这个命令就会被加载到AOF文件的末尾,这种做法,使得当重新启动Redis时,加载该AOF文件即可恢复完整的数据集。
AOF重写
正如我们能够猜到的那样,AOF文件将会随着写入命令的不断增加,变得越来越大。举个例子,我们对计数器counter增加100次,那么仅仅是为了保存这个计数器中最后的值,AOF文件需要使用100次记录。其中的99条记录对于恢复数据状态是非必需的。AOF有多么耐久?
AOF出错了怎么办?
- 为现有的AOF文件进行备份。
- 使用Redis负载的redis-check-aof工具来对原来的AOF文件进行修复。
redis-check-aof --fix
- 可选的,使用diff -u 对比修复后的AOF文件与原始AOF的备份,查看两份文件不同之处。
- 重启Redis服务器,等待服务器载入修复后的AOF文件,并进行数据恢复。
AOF的工作方式
- Redis执行fork,同时拥有父进程与子进程。
- 子进程开始将AOF文件写到临时文件中。
- 父进程累积所有新的变化到内存缓存中。(同时将是新的变化写入旧的AOF文件中,这样即使在重写中发生故障,也能保证数据是安全的)
- 当子进程完成重写文件时,父进程会得到一个信号,之后,将内存中的缓存数据追加到新的AOF文件末尾。
- 搞定!现在Redis原子的替换掉有文件,之后所有的文件追加动作都会针对新的AOF文件进行。
如果我正在使用RDB快照模式,怎么切换到AOF文件?
- 为最新的dump.rdb文件创造备份文件。
- 将备份文件放在一个安全的地方。
- 执行下面的两条命令:
redis-cli> config set appendonly yesredis-cli> config set save ""
- 确保命令执行之后,数据库的键的数量没有改变。
- 确保写命令会被正确的追加到AOF文件的末尾。
AOF与RDB之间的相互作用:
备份Redis数据:
容灾备份:
- Amazon S3,以及其他类似的服务,是一个构建容灾备份系统的好地方。最简单的方法就是将你的每小时,每天的RDB快照加密传送到S3服务中。对数据的加密可以通过“gpg -c”命令完成(对称加密模式)。同时确保把你的密码放置到不同的安全的地方。(比如把密码交给组织结构中关键人物)。另外,推荐的做法是:使用多个存储服务来提高数据的安全性。
- 传送快照可以使用SCP(SSH的组件)来完成传输。一下是简单并且安全的传送方法:购买一个离数据中心较远的VPS,装上SSH,创建一个无密码的SSH客户端key,并将这个key添加到VPS的授权文件中,这样就可以向这个VPS传送备份的快照文件了。为了达到最好的数据安全性,最少要从两个不同的提供商那里购买一个VPS来进行数据容灾备份。