配置方案:Redis持久化RDB和AOF

Redis持久化方案linux

Redis是内存数据库,数据都是存储在内存中,为了不进程退出致使数据的永久丢失,须要按期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘。当下次Redis重启时,利用持久化文件实现数据恢复。除此以外,为了进行灾难备份,能够将持久化文件拷贝到一个远程位置。redis

Redis提供了多种不一样级别的持久化方式:一种是RDB,另外一种是AOF。算法

RDB持久化能够在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot),将数据库的快照(snapshot)以二进制的方式保存到磁盘中。数据库

AOF持久化记录服务器执行的全部更改操做命令,AOF文件中的命令所有以Redis协议的格式来保存,新命令会被追加到文件的末尾。Redis还能够在后台对AOF文件进行重写(rewrite),使得AOF文件的体积不会超出保存数据集状态所需的实际大小。缓存

Redis能够同时使用AOF持久化和RDB持久化。在这种状况下,当Redis重启时,它会优先使用AOF文件来还原数据集,由于AOF文件保存的数据集一般比RDB文件所保存的数据集更完整。你甚至能够关闭持久化功能,让数据只在服务器运行时存在。安全

了解RDB持久化和AOF持久化之间的异同是很是重要的,如下几个小节将详细地介绍这这两种持久化功能,并对它们的相同和不一样之处进行说明。服务器

RDB快照网络

下面咱们说一下Redis的第一个持久化策略,RDB快照。Redis支持将当前内存数据的快照存成一个数据文件的持久化机制,而一个持续写入的数据库如何生成快照呢?Redis巧妙地借助了fork命令的写时复制(copy on write)机制,将当前进程fork出一个子进程,子进程根据内存快照,循环将数据持久化为RDB文件。app

在默认状况下, Redis将数据库快照保存在根目录下,名字为dump.rdb的二进制文件中。可经过参数dir配置指定保存目录,dbfilename指定文件名。你能够对Redis进行设置,如“save N M”,表示N秒内数据项中有M个改动时这一条件被知足时,自动保存一次数据集。好比你能够配置当10分钟之内有100次写入就生成快照,也能够配置当1分钟内有1000次写入就生成快照,支持能够多个规则一块儿生效,当匹配到哪一个就哪一个规则生效。这些规则的定义就在Redis的配置文件中,你也能够经过Redis的CONFIG SET命令在Redis运行时设置规则,不须要重启Redis。async

好比说,如下设置会让Redis在知足“60秒内有至少有1000个键被改动”这一条件时,自动保存一次数据集:

save 60 1000

你也能够经过调用SAVE或者BGSAVE,手动让Redis进行数据集保存操做。SAVE命令执行一个同步操做,以RDB文件的方式保存全部数据的快照,不多在生产环境直接使用SAVE命令,由于它会阻塞全部的客户端的请求,不要在生产环境使用,可使用BGSAVE命令代替。BGSAVE命令执行过程当中是经过fork一个子进程来完成的,因此不会阻塞客户端请求,只有fork子进程时会阻塞服务器。另外,在自动触发RDB持久化时,Redis也会选择BGSAVE而不是SAVE来进行持久化。

Redis自动RDB持久化在其内部是经过serverCron周期性操做函数、dirty计数器、和lastsave时间戳来实现的。其中serverCron每100ms执行一次,检查服务器状态,其中就包括检查“save N M”是否知足条件,若是知足就执行BGSAVE;固然也包括AOF重写检查。dirty计数器是Redis服务器维持的一个状态,记录了上一次执行BGSAVE/SAVE命令后,服务器状态进行了多少次修改(包括增删改),而当BGSAVE/SAVE执行完成后,会将dirty从新置为0。lastsave时间戳也是Redis服务器维持的一个状态,记录的是上一次成功执行BGSAVE/SAVE的时间,当前时间减去lastsave需知足M。

除了手动和自动之外,还有一些其余状况会触发BGSAVE:

在主从复制场景下,若是从节点执行全量复制操做,则主节点会执行BGSAVE命令,并将rdb文件发送给从节点。
执行shutdown命令时,自动执行rdb持久化。
另外须要了解的,由于其写操做是在一个新进程中进行的,当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,而后经过原子性rename系统调用将临时文件重命名为RDB文件,这样在任什么时候候出现故障,Redis的RDB文件都老是可用的。

这种持久化方式被称为快照(snapshot)。可是,咱们能够很明显的看到,RDB有他的不足,就是一旦数据库出现问题,那么咱们的RDB文件中保存的数据并非全新的,从上次RDB文件生成到Redis停机这段时间的数据所有丢掉了。在某些业务下,若是能够忍受间隔内数据丢失,咱们也推荐这些业务使用RDB的方式进行持久化,由于开启RDB的代价并不高。可是对于另一些对数据安全性要求极高的应用,没法容忍数据丢失的应用,RDB就无能为力了,因此Redis引入了另外一个重要的持久化机制,AOF日志方式持久化。

为了尽量使RDB文件体积减少,Redis默认采用LZF算法对RDB文件进行压缩。虽然压缩耗时,可是能够大大减少RDB文件的体积,所以压缩默认开启,参数为rdbcompression。须要注意的是,RDB文件的压缩并非针对整个文件进行的,而是对数据库中的字符串进行的,且只有在字符串达到必定长度(20字节)时才会进行。

除了压缩,你也能够检验RDB文件,经过参数rdbchecksum设置,默认为yes。在写入文件和读取文件时都起做用,关闭checksum在写入文件和启动文件时大约能带来10%的性能提高,可是数据损坏时没法发现。

另外,当bgsave出现错误时,Redis是否中止执行写命令。Redis提供了一个参数stop-writes-on-bgsave-error,设置为yes,则当硬盘出现问题时,能够及时发现,避免数据的大量丢失;设置为no,则Redis无视bgsave的错误继续执行写命令,当对Redis服务器的系统(尤为是硬盘)使用了监控时,该选项考虑设置为no。

说说FORK的开销?

父进程经过fork操做能够建立子进程,第一代Unix系统实现了一种傻瓜式的进程建立:当执行fork系统调用时,内核复制父进程的整个用户空间并把复制获得的那一份分配给子进程。这种行为时很是耗时的,由于它须要完成如下几项任务:为子进程的页表分配页面、为子进程的页分配页面、初始化子进程的页表、把父进程的页复制到子进程对应的页中。

如今Linux的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝是一种能够推迟甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。只有在须要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。也就是说,资源的复制只有在须要写入的时候才进行,在此以前,只是以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候。因此就算fork很大内存的进程,对内存的消耗和耗时都很小。

如今虽然fork时,子进程不会复制父进程的数据空间,可是会复制内存页表(页表至关于内存的索引、目录);父进程的数据空间越大,内存页表越大,fork时复制耗时也会越多。这个问题也是致使Redis内存不宜过大的缘由之一,固然还有致使故障恢复时间延长也是Redis内存不宜过大的缘由。

AOF日志

经过上面的分析,咱们知道RDB快照有大几率丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来讲,数据安全并非最重要的考虑因素,可是对于那些追求数据安全的程序来讲,快照功能就不太适用了。从1.1版本开始,Redis增长了一种实时性更好的持久化方式,即AOF持久化。AOF日志的全称是append only file,从名字上咱们就能看出来,它是一个追加写入的日志文件。与RDB相比,AOF的实时性更好,所以已成为主流的持久化方案。

AOF文件与MySQL数据库的binlog不一样的是,AOF是一种纯文本格式,具备兼容性好、可读性强、容易处理、操做简单避免二次开销等优势,它记录的内容就是一个个的Redis标准命令。开启AOF持久化命令以下:

appendonly yes
appendfilename "appendonly.aof"

从如今开始,每当Redis执行一个改变数据集的命令时(好比SET),这个命令就会被追加到AOF文件的末尾。这样的话,当Redis从新启时,程序就能够经过从新执行AOF文件中的命令来达到重建数据集的目的。

因为须要记录Redis的每条写命令,所以AOF不须要触发,下面介绍AOF的执行流程:

命令追加(append)

Redis先将写命令追加到缓冲区,而不是直接写入文件,主要是为了不每次有写命令都直接写入硬盘,致使硬盘IO成为Redis负载的瓶颈。

文件写入(write)和文件同步(sync)

Redis提供了多种AOF缓存区的同步文件策略,策略涉及到操做系统的write函数和fsync函数,说明以下:

为了提升文件写入效率,在现代操做系统中,当用户调用write函数将数据写入文件时,操做系统一般会将数据暂存到一个内存缓冲区里,当缓冲区被填满或超过了指定时限后,才真正将缓冲区的数据写入到硬盘里。这样的操做虽然提升了效率,但也带来了安全问题:若是计算机停机,内存缓冲区中的数据会丢失;所以系统同时提供了fsync、fdatasync等同步函数,能够强制操做系统马上将缓冲区中的数据写入到硬盘里,从而确保数据的安全性。

AOF缓存区的同步文件策略由参数appendfsync控制,各个值的含义以下:

always:命令写入aof_buf后当即调用系统fsync操做同步到AOF文件,fsync完成后线程返回。这种状况下,每次有写命令都要同步到AOF文件,硬盘IO成为性能瓶颈,Redis只能支持大约几百TPS写入,严重下降了Redis的性能;即使是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,并且会大大下降SSD的寿命。

no:命令写入aof_buf后调用系统write操做,不对AOF文件作fsync同步;同步由操做系统负责,一般同步周期为30秒。这种状况下,文件同步的时间不可控,且缓冲区中堆积的数据会不少,数据安全性没法保证。
everysec:命令写入aof_buf后调用系统write操做,write完成后线程返回;fsync同步文件操做由专门的线程每秒调用一次。everysec是前述两种策略的折中,是性能和数据安全性的平衡,所以是Redis的默认配置,也是咱们推荐的配置。

文件重写(rewrite)

由于AOF的运做方式是不断地将命令追加到文件的末尾,因此随着写入命令的不断增长,AOF文件的体积也会变得愈来愈大。举个例子,若是你对一个计数器调用了100次INCR,那么仅仅是为了保存这个计数器的当前值,AOF文件就须要使用100条记录(entry)。然而在实际上,只使用一条SET命令已经足以保存计数器的当前值了,其他99条记录实际上都是多余的。另外还有一些过时的数据,无效的数据也都是能够去除。

过大的AOF文件不只会影响服务器的正常运行,也会致使数据恢复须要的时间过长。为了处理这种状况,Redis支持一种有趣的特性,能够在不打断服务客户端的状况下,对AOF文件进行重建(rebuild)。执行BGREWRITEAOF命令, Redis将生成一个新的AOF文件, 这个文件包含重建当前数据集所需的最少命令。

AOF REWRITE(重写)生成过程和RDB快照相似,都巧妙地利用了写时复制机制。一样也是fork一个子进程(此时主线程是阻塞的),子进程根据内存快照,按照命令合并规则写入到新的AOF文件。当主进程fork完子线程后继续接受请求,全部写命令依然写入AOF缓冲区(aof_buf),并根据appendfsync策略同步到硬盘,保证原有AOF机制的正确。但因为fork操做使用写时复制技术,子进程只能共享fork操做时的内存数据。因为父进程依然在响应命令,所以Redis使用AOF重写缓冲区(aof_rewrite_buf)保存这部分新日志,防止新AOF文件生成期间丢失这部分数据。也就是说,bgrewriteaof执行期间,Redis的写命令同时追加到aof_buf和aof_rewirte_buf两个缓冲区。

当子进程写完新的AOF文件后,向父进程发信号,父进程更新统计信息,具体能够经过info persistence查看。而后父进程把AOF重写缓冲区的数据写入到新的AOF文件,这样就保证了新AOF文件所保存的数据库状态和服务器当前状态一致。而后调用原子性的rename命令用新的AOF文件取代老的AOF文件,完成AOF重写。

这里须要注意,由于由主进程把aof_rewrite_buf缓存追加到新日志文件。主进程追加日志时,不会处理其余请求,若是aof_rewrite_buf特别大,例如几百M,也可能形成Redis几秒甚至几十秒不响应。

从上面的流程咱们可以看到,RDB和AOF操做都是顺序IO操做,性能都很高。而在经过RDB文件或者AOF日志进行数据库恢复的时候,也是顺序的读取数据加载到内存中。因此也不会形成磁盘的随机读。

文件重写的触发,分为手动触发和自动触发:

手动触发:直接调用bgrewriteaof命令,该命令的执行与bgsave有些相似:都是fork子进程进行具体的工做,且都只有在fork时阻塞。

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数,以及aof_current_size和aof_base_size状态肯定触发时机。

auto-aof-rewrite-min-size表示执行AOF重写时,文件的最小体积,默认值为64MB。

auto-aof-rewrite-percentage表示执行AOF重写时,当前AOF大小(即aof_current_size)和上一次重写时AOF大小(aof_base_size)的比值,即增加比例达到设定值。

只有当auto-aof-rewrite-min-size和auto-aof-rewrite-percentage两个参数同时知足时,才会自动触发AOF重写,即bgrewriteaof操做。

其中,参数能够经过config get命令查看:

127.0.0.1:6391> CONFIG GET auto-aof-rewrite-min-size
1) "auto-aof-rewrite-min-size"
2) "64000000"
127.0.0.1:6391> CONFIG GET auto-aof-rewrite-percentage
1) "auto-aof-rewrite-percentage"
2) "100"

状态能够经过info persistence查看:

127.0.0.1:6379> info persistence
# Persistence
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:0
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_current_size:40876638
aof_base_size:2217565
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

另外在aof rewrite过程当中,是否采起增量”文件同步”策略,由参数aof-rewrite-incremental-fsync控制,默认为”yes”,并且必须为yes。rewrite过程当中,每32M数据进行一次文件同步,这样能够减小”aof大文件”写入对磁盘的操做次数。

bgrewriteaof机制,在一个子进程中进行aof的重写,从而不阻塞主进程对其他命令的处理,同时解决了aof文件过大问题。如今问题出现了,同时在执行bgrewriteaof操做和主进程写aof文件的操做,二者都会操做磁盘,而bgrewriteaof每每会涉及大量磁盘操做,这样就会形成主进程在写aof文件的时候出现阻塞的情形,如今no-appendfsync-on-rewrite参数出场了。

若是该参数设置为no,是最安全的方式,不会丢失数据,可是要忍受阻塞的问题。若是设置为yes呢?这就至关于将appendfsync设置为no,这说明并无执行磁盘操做,只是写入了缓冲区,所以这样并不会形成阻塞(由于没有竞争磁盘),可是若是这个时候Redis挂掉,就会丢失数据。丢失多少数据呢?在Linux的操做系统的默认设置下,最多会丢失30s的数据。所以,若是应用系统没法忍受延迟,而能够容忍少许的数据丢失,则设置为yes。若是应用系统没法忍受数据丢失,则设置为no。

AOF刷新策略?

前面提到过,在AOF中,若是AOF缓冲区的文件同步策略为everysec,则:在主线程中,命令写入aof_buf后调用系统write操做,write完成后主线程返回;fsync同步文件操做由专门的文件同步线程每秒调用一次。这种作法的问题在于,若是硬盘负载太高,那么fsync操做可能会超过1s;若是Redis主线程持续高速向aof_buf写入命令,硬盘的负载可能会愈来愈大,IO资源消耗更快;若是此时Redis进程异常退出,丢失的数据也会愈来愈多,可能远超过1s。

为此,Redis的处理策略是这样的:主线程每次进行AOF会对比上次fsync成功的时间;若是距上次不到2s(也就是延迟了1s),主线程直接返回;若是超过2s,则主线程阻塞直到上一次fsync同步完成。所以,若是系统硬盘负载过大致使fsync速度太慢,会致使Redis主线程的阻塞;此外,使用everysec配置,AOF最多可能丢失2s的数据,而不是1s。具体看Redis AOF刷新策略分析

AOF追加阻塞问题定位的方法,监控info Persistence中的aof_delayed_fsync,当AOF追加阻塞发生时(即主线程等待fsync而阻塞),该指标累加。另外,AOF阻塞时的Redis日志:Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.

若是AOF追加阻塞频繁发生,说明系统的硬盘负载太大;能够考虑更换IO速度更快的硬盘,或者经过IO监控分析工具对系统的IO负载进行分析。

对于pipelining有什么不一样?

对于pipelining的操做,其具体过程是客户端一次性发送N个命令,而后等待这N个命令的返回结果被一块儿返回。经过采用pipilining就意味着放弃了对每个命令的返回值确认。因为在这种状况下,N个命令是在同一个执行过程当中执行的。因此当设置appendfsync为everysec时,可能会有一些误差,由于这N个命令可能执行时间超过1秒甚至2秒。可是能够保证的是,最长时间不会超过这N个命令的执行时间和。

若是AOF文件出错了,怎么办?

服务器可能在程序正在对AOF文件进行写入时停机,若是停机形成了 AOF 文件出错(corrupt),那么Redis在重启时会拒绝载入这个AOF文件, 从而确保数据的一致性不会被破坏。当发生这种状况时,能够用如下方法来修复出错的 AOF 文件:为现有的AOF文件建立一个备份。而后使用Redis附带的redis-check-aof --fix程序对原来的AOF文件进行修复。

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

但若是是AOF文件结尾不完整(机器忽然宕机等容易致使文件尾部不完整),且aof-load-truncated参数开启,则日志中会输出警告,Redis忽略掉AOF文件的尾部,启动成功。aof-load-truncated参数默认是开启的。

RDB和AOF优缺点

RDB的优势?

RDB是一个很是紧凑(compact)的文件,体积小,网络传输快,它保存了Redis在某个时间点上的数据集。这种文件很是适合用于进行备份,恢复速度比AOF快不少。固然,与AOF相比,RDB最重要的优势之一是对性能的影响相对较小。父进程在保存RDB文件时惟一要作的就是fork出一个子进程,而后这个子进程就会处理接下来的全部保存工做,父进程无须执行任何磁盘 I/O 操做。

RDB的缺点?

RDB文件的致命缺点在于其数据快照的持久化方式决定了必然作不到实时持久化,而在数据愈来愈重要的今天,数据的大量丢失不少时候是没法接受的,所以AOF持久化成为主流。此外,RDB文件须要知足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。

AOF的优势?

与RDB持久化相对应,AOF的优势在于支持秒级持久化、兼容性好。你能够设置不一样的fsync策略,好比无fsync,每秒钟一次fsync,或者每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,Redis仍然能够保持良好的性能,而且就算发生故障停机,也最多只会丢失一秒钟的数据。AOF文件是一个只进行追加操做的日志文件(append only log),所以对AOF文件的写入不须要进行seek(查找),即便日志由于某些缘由而包含了未写入完整的命令(好比写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也能够轻易地修复这种问题。

Redis能够在AOF文件体积变得过大时,自动地在后台对AOF进行重写: 重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。 整个重写操做是绝对安全的,由于 Redis 在建立新 AOF 文件的过程当中,会继续将命令追加到现有的AOF文件里面,即便重写过程当中发生停机,现有的AOF文件也不会丢失。 而一旦新AOF文件建立完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操做。AOF文件有序地保存了对数据库执行的全部写入操做,这些写入操做以Redis协议的格式保存,所以AOF文件的内容很是容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也很是简单: 举个例子, 若是你不当心执行了FLUSHALL命令,但只要AOF文件未被重写,那么只要中止服务器,移除AOF文件末尾的FLUSHALL命令,并重启 Redis, 就能够将数据集恢复到FLUSHALL执行以前的状态。

AOF的缺点?

AOF文件的体积一般要大于RDB文件的体积、且恢复速度慢。对于相同的数据集来讲,根据所使用的fsync策略,AOF的速度可能会慢于RDB。在通常状况下,每秒fsync的性能依然很是高,而关闭fsync可让AOF的速度和RDB同样快。另外,AOF在过去曾经发生过这样的bug,由于个别命令的缘由,致使AOF文件在从新载入时,没法将数据集恢复成保存时的原样。虽然这种bug在AOF文件中并不常见,可是对比来讲,RDB几乎是不可能出现这种bug的。

RDB和AOF,我应该用哪个?

首先要明白不管是RDB仍是AOF,持久化的开启都是要付出性能方面代价的:对于RDB持久化,一方面是bgsave在进行fork操做时Redis主进程会阻塞,另外一方面,子进程向硬盘写数据也会带来IO压力。但若是业务能容忍几分钟到10几分钟的数据丢失(且不使用备库),RDB是一个不错的选择;否则,就选择AOF。

对于AOF持久化,向硬盘写数据的频率大大提升(everysec策略下为秒级),IO压力更大,甚至可能形成AOF追加阻塞问题(后面会详细介绍这种阻塞),此外,AOF文件的重写与RDB的bgsave相似,会有fork时的阻塞和子进程的IO压力问题。相对来讲,因为AOF向硬盘中写数据的频率更高,所以对Redis主进程性能的影响会更大。

在实际生产环境中,根据数据量、应用对数据的安全要求、预算限制等不一样状况,会有各类各样的持久化策略;如彻底不使用任何持久化、使用RDB或AOF的一种,或同时开启RDB和AOF持久化等。此外,持久化的选择必须与Redis的主从策略一块儿考虑,由于主从复制与持久化一样具备数据备份的功能,并且主机master和从机slave能够独立的选择持久化方案。好比彻底关闭master持久化(包括RDB和AOF),这样可让master的性能达到最好;而slave能够只开启AOF。但这种状况下,若是master服务由于故障宕掉了,若是系统中有自动拉起机制(即检测到服务中止后重启该服务)将master自动重启,因为没有持久化文件,那么master重启后数据是空的,slave同步数据也变成了空的,意味着数据丢失。因此尽可能避免这种状况出现。

RDB和AOF之间的相互做用?

在版本号大于等于2.4的Redis中,BGSAVE执行的过程当中,不能够执行BGREWRITEAOF。反过来讲,在BGREWRITEAOF执行的过程当中,也不能够执行BGSAVE。这能够防止两个Redis后台进程同时对磁盘进行大量的I/O操做。

若是BGSAVE正在执行,而且用户显示地调用BGREWRITEAOF命令,那么服务器将向用户回复一个OK状态,并告知用户,BGREWRITEAOF已经被预约执行: 一旦BGSAVE执行完毕,BGREWRITEAOF就会正式开始。当Redis启动时,若是RDB持久化和AOF持久化都被打开了,那么程序会优先使用AOF文件来恢复数据集,由于AOF文件所保存的数据一般是最完整的。

RDB和AOF数据导入

这些持久化的数据有什么用,固然是用于重启后的数据恢复。Redis是一个内存数据库,不管是RDB仍是AOF,都只是其保证数据恢复的措施。因此Redis在利用RDB或AOF进行恢复的时候,会读取RDB或AOF文件,从新加载到内存中。相对于MySQL等数据库的启动时间来讲,会长不少,由于MySQL原本是不须要将数据加载到内存中的。

可是相对来讲,MySQL启动后提供服务时,其被访问的热数据也会慢慢加载到内存中,一般咱们称之为预热,而在预热完成前,其性能都不会过高。而Redis的好处是一次性将数据加载到内存中,一次性预热。这样只要Redis启动完成,那么其提供服务的速度都是很是快的。

而在利用RDB和利用AOF启动上,其启动时间有一些差异。RDB的启动时间会更短,缘由有两个,一是RDB文件中每一条数据只有一条记录,不会像AOF日志那样可能有一条数据的屡次操做记录。因此每条数据只须要写一次就好了。另外一个缘由是RDB文件的存储格式和Redis数据在内存中的编码格式是一致的,不须要再进行数据编码工做。在CPU消耗上要远小于AOF日志的加载。

注意:当redis启动时,若是rdb持久化和aof持久化都打开了,那么程序会优先使用aof方式来恢复数据集,由于aof方式所保存的数据一般是最完整的。若是aof文件丢失了,则启动以后数据库内容为空。

注意:若是想把正在运行的redis数据库,从RDB切换到AOF,建议先使用动态切换方式,再修改配置文件,重启数据库。(不能直接修改配置文件,重启数据库,不然数据库中数据就为空了。)
在Redis 2.2或以上版本,能够在不重启的状况下,从RDB切换到AOF :

为最新的dump.rdb文件建立一个备份,将备份放到一个安全的地方。执行如下两条命令:

127.0.0.1:6379> CONFIG SET dir /apps/redis/data/redis-8836
127.0.0.1:6379> CONFIG SET appendonly yes
127.0.0.1:6379> CONFIG SET save ""

确保命令执行以后,数据库的键的数量没有改变。确保写命令会被正确地追加到 AOF 文件的末尾。

步骤2是开启了AOF功能,Redis会阻塞直到初始AOF文件建立完成为止,以后Redis会继续处理命令请求,并开始将写入命令追加到AOF文件末尾。

步骤3用于关闭RDB功能,这一步是可选的,若是你愿意的话,也能够同时使用RDB和AOF这两种持久化功能。

相关文章
相关标签/搜索