Redis实战和核心原理详解--快照RDB和AOF数据持久化、RDB和AOF的优缺点对比以及如何选择

https://blog.csdn.net/xlgen157387/article/details/61925524
https://blog.csdn.net/xlgen157387/article/details/89208221
一、前言
我们知道Redis是一款内存服务器,就算我们对自己的服务器足够的信任,不会出现任何软件或者硬件的故障,但也会有可能出现突然断电等情况,造成Redis服务器中的数据失效。因此,我们需要向传统的关系型数据库一样对数据进行备份,将Redis在内存中的数据持久化到硬盘等非易失性介质中,来保证数据的可靠性。

将Redis内存服务器中的数据持久化到硬盘等介质中的一个好处就是,使得我们的服务器在重启之后还可以重用以前的数据,或者是为了防止系统出现故障而将数据备份到一个远程的位置。

还有一些场景,例如:

对于一些需要进行大量计算而得到的数据,放置在Redis服务器,我们就有必要对其进行数据的持久化,如果需要对数据进行恢复的时候,我们就不需进行重新的计算,只需要简单的将这台机器上的数据复制到另一台需要恢复的Redis服务器就可以了。

Redis中数据存储模式有2种:

cache-only,即只做为“缓存”服务,不持久数据,数据在服务终止后将消失,此模式下也将不存在“数据恢复”的手段,是一种安全性低/效率高/容易扩展的方式;

persistence,即为内存中的数据持久备份到磁盘文件,在服务重启后可以恢复,此模式下数据相对安全。

对于persistence持久化存储,Redis提供了两种持久化方法:

Redis DataBase(简称RDB),快照(Snapshotting) ;
Append-only file (简称AOF),只追加文件(append-only-file) ;
除了这两种方法,Redis在早起的版本还存在虚拟内存的方法,现在已经被废弃。

1.1、名词简介
(1)快照(RDB):就是我们俗称的备份,他可以在定期内对数据进行备份,将Redis服务器中的数据持久化到硬盘中;

文件格式是:dump.rdb

RDB持久化机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,在替换之前的文件,用二进制压缩存储。

(2)只追加文件(AOF):他会在执行写命令的时候,将执行的写命令复制到硬盘里面,后期恢复的时候,只需要重新执行一下这个写命令就可以了。类似于我们的MySQL数据库在进行主从复制的时候,使用的是binlog二进制文件,同样的是执行一遍写命令;AOF会记录每一个写、删除操作,查询操作不会被记录,以文件的形式记录,可以打开文件看到详细的操作记录。

文件格式是:appendonly.aof

1.2、快照RDB持久化通用的配置:
save 60 1000 #60秒时间内有1000次写入操作的时候执行快照的创建
stop-writes-on-bgsave-error no #创建快照失败的时候是否仍然继续执行写命令
rdbcompression yes #是否对快照文件进行压缩
dbfilename dump.rdb #如何命名硬盘上的快照文件
dir ./ #快照所保存的位置
1
2
3
4
5
1.3、AOP持久化配置:
appendonly no #是否使用AOF持久化
appendfsync everysec #多久执行一次将写入内容同步到硬盘上
no-appendfsync-on-rewrite no #对AOF进行压缩的时候能否执行同步操作
auto-aof-rewrite-percentage 100 #多久执行一次AOF压缩
auto-aof-rewrite-min-size 64mb #多久执行一次AOF压缩
dir ./ #AOF所保存的位置
1
2
3
4
5
6
需要注意的是:这两种持久化的方式既可以单独的使用,也可以同时使用,具体选择哪种方式需要根据具体的情况进行选择。

二、RDB快照持久化
快照就是我们所说的备份。用户可以将Redis内存中的数据在某一个时间点进行备份,在创建快照之后,用户可以对快照进行备份。通常情况下,为了防止单台服务器出现故障造成所有数据的丢失,我们还可以将快照复制到其他服务器,创建具有相同数据的数据副本,这样的话,数据恢复的时候或者服务器重启的时候就可以使用这些快照信息进行数据的恢复,也可以防止单台服务器出现故障的时候造成数据的丢失。

但是,没我们还需要注意的是,创建快照的方式,并不能完全保证我们的数据不丢失,这个大家可以很好的理解,因为快照的创建时定时的,并不是每一次更新操作都会创建一个快照的。系统发生崩溃的时候,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化的方式只适合于数据不经常修改或者丢失部分数据影响不大的场景。

2.1、创建快照的方式:
(1)客户端通过向Redis发送BGSAVE 命令来创建快照。

使用BGSAVE的时候,Redis会调用fork来创建一个子进程,然后子进程负责将快照写到硬盘中,而父进程则继续处理命令请求。

使用场景:

如果用户使用了save设置,例如:save 60 1000 ,那么从Redis最近一次创建快照之后开始计算,当“60秒之内有1000次写入操作”这个条件满足的时候,Redis就会自动触发BGSAVE命令。

如果用户使用了多个save设置,那么当任意一个save配置满足条件的时候,Redis都会触发一次BGSAVE命令。

(2)客户端通过向Redis发送SAVE 命令来创建快照。

接收到SAVE命令的Redis服务器在快照创建完毕之前将不再响应任何其他命令的请求。SAVE命令并不常用,我们通常只在没有足够的内存去执行BGSAVE命令的时候才会使用SAVE命令,或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令;

使用场景:

当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准的TERM信号时,会执行一次SAVE命令,阻塞所有的客户端,不再执行客户端发送的任何命令,并且在执行完SAVE命令之后关闭服务器。

2.2、命令的含义:
RDB持久化会对redis中的数据进行周期性的持久化,生成一份快照文件,存放在配置文件声明的目录下面的dump.rdb文件。在redis配置文件中可以通过配置dir属性来指定持久化文件存放目录。默认情况下RDB持久化是打开的,可以在配置文件中找到如下内容:

save 900 1
save 300 10
save 60 10000
1
2
3
上述命令指的是如果900秒内有1个key发生了变化,生成一份快照文件,如果再300秒内有10个key发生了改变,生成一份快照文件,如果在60秒内有10000个key发生了改变,生成一份快照文件。

save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去检查一下,是否有指定的key数量发生变化,如果有就生成一个新的dump.rdb文件。

也可以通过save或者bgsave命令同步或异步指定rdb快照生成。

save命令的注意事项:

save 900 1
1
这条命令指的是两个数字同时生效的时候,才会执行具体的RDB,并不是到了900秒或者有一条数据已经发生了改变就进行RDB了,两个条件是同时满足的!官网的解释说明了这个问题,

2.3、RDB持久化的工作流程:

具体流程如下:

Redis根据配置自己尝试生成RDB快照文件;
fork一个子进程出来;
子进程尝试将数据写到临时的RDB快照文件中;
完成RDB快照文件的生成之后,就替换之前旧的快照文件;
dump.rdb 每次生成一个快照,都会覆盖之前的旧文件。

2.4、使用RDB快照持久化注意事项:
我们在使用快照的方式来保存数据的时候,如果Redis服务器中的数据量比较小的话,例如只有几个GB的时候。Redis会创建子进程并将数据保存到硬盘里边,生成快照所需的时间比读取数据所需要的时间还要短。

但是,随着数据的增大,Redis占用的内存越来越大的时候,BGSAVE在创建子进程的时候消耗的时间也会越来越多,如果Redis服务器所剩下的内存不多的时候,这行BGSAVE命令会使得系统长时间地停顿,还有可能导致服务器无法使用。

各虚拟机类别,创建子线程所耗时间:

因此,为了防止Redis因为创建子进程的时候出现停顿,我们可以考虑关闭自动保存,转而通过手动的方式发送BGSAVE或者SAVE来进行持久化,

手动的方式发送BGSAVE也会出现停顿的现象,但是我们可以控制发送该命令的时间来控制出现停顿的时候不影响具体的业务请求。

另外,值得注意的是,在使用SAVE命令的时候,虽然会一直阻塞Redis直到快照生成完毕,但是其不需要创建子进程,所以不会向BGSAVE一样,因为创建子进程而导致Redis停顿。也正因为如此,SAVE创建快照的速度要比BGSAVE创建快照的速度更快一些。

创建快照的时候,我们可以在业务请求,比较少的时候,比如凌晨三、四点,通过手写脚本的方式,定时执行。

三、AOF持久化
AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。这样,我们在恢复数据的时候,只需要从头到尾的执行一下AOF文件即可恢复数据。

3.1、打开AOF持久化选项
我们可以通过使用如下命令打开AOF:

appendonly yes
1
我们,通过如下命令来配置AOF文件的同步频率:

appendfsync everysec/always/no
1
3.2、appendfsync同步频率的区别
appendfsync同步频率的区别如下图:

(1)always的方式固然可以对没一条数据进行很好的保存,但是这种同步策略需要对硬盘进行大量的写操作,所以Redis处理命令的速度会受到硬盘性能的限制。

普通的硬盘每秒钟只能处理大约200个写命令,使用固态硬盘SSD每秒可以处理几万个写命令,但是每次只写一个命令,这种只能怪不断地写入很少量的数据的做法有可能引发严重的写入放大问题,这种情况下降严重影响固态硬盘的使用寿命。

(2)everysec的方式,Redis以每秒一次的频率大队AOF文件进行同步。这样的话既可以兼顾数据安全也可以兼顾写入性能。

Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性时的性能相差无几,使用每秒更新一次 的方式,可以保证,即使出现故障,丢失的数据也在一秒之内产生的数据。

(3)no的方式,Redis将不对AOF文件执行任何显示的同步操作,而是由操作系统来决定应该何时对AOF文件进行同步。

这个命令一般不会对Redis的性能造成多大的影响,但是当系统出现故障的时候使用这种选项的Redis服务器丢失不定数量的数据。

另外,当用户的硬盘处理写入操作的速度不够快的话,那么缓冲区被等待写入硬盘的数据填满时,Redis的写入操作将被阻塞,并导致Redis处理命令请求的速度变慢,因为这个原因,一般不推荐使用这个选项。

3.3、重写/压缩AOF文件
随着数据量的增大,AOF的文件可能会很大,这样在每次进行数据恢复的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户可以向Redis发送BGREWRITEAOF 命令,这个命令会通过移除AOF文件中的冗余命令来重写AOF文件,是AOF文件的体检变得尽可能的小。

BGREWRITEAOF的工作原理和BGSAVE的原理很像:Redis会创建一个子进程,然后由子进程负责对AOF文件的重写操作。

因为AOF文件重写的时候会创建子进程,所以快照持久化因为创建子进程而导致的性能和内存占用问题同样会出现在AOF文件重写的 时候。

3.4、触发重写/压缩AOF文件条件设定
AOF通过设置auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 选项来自动执行BGREWRITEAOF。

其具体含义,通过实例可以看出,如下配置:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
1
2
表示当前AOF的文件体积大于64MB,并且AOF文件的体积比上一次重写之后的体积变大了至少一倍(100%)的时候,Redis将执行重写BGREWRITEAOF命令。

如果AOF重写执行的过于频繁的话,可以将auto-aof-rewrite-percentage 选项的值设置为100以上,这种最偶发就可以让Redis在AOF文件的体积变得更大之后才执行重写操作,不过,这也使得在进行数据恢复的时候执行的时间变得更加长一些。

3.5、AOF工作流程

四、验证RDB快照文件和AOF文件
无论使用哪种方式进行持久化,我们在进行恢复数据的时候,Redis提供了两个命令行程序:

redis-check-aof
redis-check-dump
1
2
他们可以再系统发生故障的时候,检查快照和AOF文件的状态,并对有需要的情况对文件进行修复。

如果用户在运行redis-check-aof命令的时候,指定了–fix 参数,那么程序将对AOF文件进行修复。

程序修复AOF文件的方法很简单:他会扫描给定的AOF文件,寻找不正确或者不完整的命令,当发现第一个出现错误命令的时候,程序会删除出错命令以及出错命令之后的所有命令,只保留那些位于出错命令之前的正确命令。大部分情况,被删除的都是AOF文件末尾的不完整的写命令。

五、RDB和AOF的注意事项
这两种持久化的方式既可以单独的使用,也可以同时使用,具体选择哪种方式需要根据具体的情况进行选择。

如果我们想要Redis仅仅作为纯内存的缓存来用,那么我们可以禁止RDB和AOF所有的持久化机制;

通过RDB或AOF,都可以将Redis内存中的数据给持久化到磁盘上面来,然后可以将这些数据备份到别的地方去。我们一般会选择非当前机器的磁盘文件,这样可以避免由于机器损坏等因素导致磁盘数据和内存数据全部丢失,一般具有一定的隔离性。比如说将持久化的文件存放到云盘,云服务上等;

如果Redis挂了,服务器上的内存和磁盘上的数据都丢了,我们就可以从事先备份好的存放在云盘、云服务等地方的数据拷贝回来,放到指定的目录中,然后重新启动Redis,Redis就会自动根据持久化数据文件中的数据,去恢复内存中的数据,继续对外提供服务;

如果同时使用RDB和AOF两种持久化机制,那么在Redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整;

也可以通过save或者bgsave命令同步或异步指定RDB快照生成。

AOF持久化,默认是关闭的,默认是打开RDB持久化;

appendonly yes,可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓;

六、总结
上述,一起学习了两种支持持久化的方式,一方面我们需要通过快照或者AOF的方式对数据进行持久化,另一方面,我们还需要将持久化所得到的文件进行备份,备份到不同的服务器上,这样才可以尽可能的减少数据丢失的损失。

Redis实战和核心原理详解(9)RDB和AOF的优缺点对比以及如何选择
https://blog.csdn.net/xlgen157387/article/details/89208221

一、RDB的优缺点
1.1、RDB的优点
(1)RDB文件是紧凑的二进制文件,比较适合做冷备,全量复制的场景。

RDB做会生成多个文件,每个文件都代表了某一个时刻的Redis完整的数据快照;
RDB这种多个数据文件的方式,非常适合做冷备,因为大量的一个个的文件,可以每隔一定的时间,复制出来;
可以将这种完整的数据文件发送到一些远程的云服务、分布式存储上进行安全的存储,以预定好的备份策略来定期备份Redis中的数据;
AOF也可以做冷备,只有一个文件,但是你可以写个脚本,每隔一定时间,去copy一份这个文件出来,相对比较麻烦,不推荐;
问题:RDB做冷备,优势在哪儿呢?

由Redis去控制固定时长生成快照文件的事情,比较方便;

AOF,还需要自己写一些脚本去做这个事情,各种定时;
RDB数据做冷备,在最坏的情况下,提供数据恢复的时候,速度比AOF快;
(2)相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复Redis进程,更加快速;

问题:为什么恢复的时候RDB比AOF快?

AOF,存放的指令日志,做数据恢复的时候,其实是要回放和执行所有的指令日志,来恢复出来内存中的所有数据的;
RDB,就是一份数据文件,恢复的时候,直接加载到内存中即可;
RDB的时候,Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可;
(3)RDB对Redis对外提供的读写服务,影响非常小,可以让Redis保持高性能,因为Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可;

RDB每次写,都是直接写Redis内存,只是在一定的时候,才会将数据写入磁盘中;
AOF,每次都是要写文件的,虽然可以快速写入os cache中,但是还是有一定的时间开销的,速度肯定比RDB略慢一些;
(4)RDB使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了Redis的高性能 ;

1.2、RDB的缺点
(1)如果想要在Redis故障时,尽可能少的丢失数据,那么RDB没有AOF好。

一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦Redis进程宕机,那么会丢失最近5分钟的数据;

这个问题,也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果你依赖RDB做第一优先恢复方案,会导致数据丢失的比较多;

(2)RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒;

一般不要让RDB的间隔太长,否则每次生成的RDB文件太大了,对Redis本身的性能可能会有影响的;

(3)RDB无法实现实时或者秒级持久化

RDB是间隔一段时间进行持久化,如果持久化之间Redis发生故障,会发生数据丢失。

二、AOF的优缺点
2.1、AOF的优点
(1)AOF可以更好的保护数据不丢失。

一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据,Redis进程挂了,最多丢掉1秒钟的数据;

(2)AOF日志文件以append-only模式写入,写入性能比较高

AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修;

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

因为在rewrite log的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。

当新的merge后的日志文件ready的时候,再交换新老日志文件即可。

(4)适合做灾难性的误删除紧急恢复

AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据;

2.2、AOF的缺点
(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度慢;

我们可以简单的认为AOF就是日志文件,此文件只会记录“变更操作”(例如:set/del等),如果server中持续的大量变更操作,将会导致AOF文件非常的庞大,意味着server失效后,数据恢复的过程将会很长;

事实上,一条数据经过多次变更,将会产生多条AOF记录,其实只要保存当前的状态,历史的操作记录是可以抛弃的;因为AOF持久化模式还伴生了“AOF rewrite”。

(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的;

如果你要保证一条数据都不丢,也是可以的,AOF的fsync设置成没写入一条数据,fsync一次,那就完蛋了,Redis的QPS大降;

(3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来

所以说,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过AOF就是为了避免rewrite过程导致的bug,因此每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

三、RDB和AOF到底该如何选择
1、不要仅仅使用RDB,因为那样会导致你丢失很多数据;

2、也不要仅仅使用AOF,因为那样有两个问题:

你通过AOF做冷备,没有RDB做冷备,恢复速度更快;
第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug;
3、综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择;

用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值