Redis学习总结(3)之持久化操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jokeMqc/article/details/87929316

一、前言

Redis提供了两种持久化方式,一个是RDB(Redis DataBase) 和AOF ( Append Only File)

RDB,简而言之,就是在不同的时间点,将redis某一时刻存储的数据生成快照并且存储在磁盘等介质上。

AOF,就是换一种方式来实现持久化,那就是将redis执行过的所有写的指令保存下来,在redis下次重启时,将所有的指令再执行一遍,那么数据就可以进行恢复了。

其实RDB和AOF可以同时启动,在这种情况下,redis重启的话,那么会优先采用AOF 的方式来进行数据恢复,这是因为AOF恢复数据的完整性更高。

如果你没有数据持久化的需求,那么你就可以关闭RDB(默认开启)和AOF,那么redis就是一个纯内存数据库,更memcached就是一样的。

二、RDB模式

RDB方式,就是将redis某一时刻的数据持久化到磁盘中,是一种快照化的持久化方式。

Redis在进行持久化的过程中,会将数据先写入到一个临时文件中,带持久化过程都结束后,才会用这个持久化文件代替上次持久化的文件,正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。

对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。

如果进行大规模的数据恢复,并且对应数据恢复完整性不是很敏感的业务,那么RDB方式将比AOF方式更加高效。

虽然RDB有很多优点,但是它的缺点也是不可置疑的,如果你对于数据恢复的完整性非常敏感的话,那么RDB方式就不太适合你,因为即使你没5分钟持久化一次,那么都会丢失将近5分钟的数据,以redis每秒10w速度级别效率,这个问题是不可忽视的。

RDB模式是redis默认开启的,在redis.conf的配置文件中可以配置对应的参数。

扫描二维码关注公众号,回复: 5813328 查看本文章

我们可以用如下的指令来让数据保存到磁盘上,即控制RDB快照功能:

save <seconds> <changes>

如果你想禁用RDB持久化的策略,只要不设置任何save指令就可以,或者给save传入一个空字符串参数也可以达到相同效果,就像这样:

save ""

如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求。这样做的好处在于可以让用户很明确的知道内存中的数据和磁盘上的数据已经存在不一致了。如果redis不顾这种不一致,一意孤行的继续接收写请求,就可能会引起一些灾难性的后果。

如果下一次RDB持久化成功,redis会自动恢复接受写请求。当然,如果你不在乎这种数据不一致或者有其他的手段发现和控制这种不一致的话,你完全可以关闭这个功能,以便在快照写入失败时,也能确保redis继续接受新的写请求。配置项如下:

stop-writes-on-bgsave-error yes

对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。

在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果你希望获取到最大的性能提升,可以关闭此功能。

设置快照文件的名称,默认是这样配置的:

三、AOF-Append Only File

AOF,英文名称 Append Only File,即只允许追加文件而不允许改变文件。

AOF的方式就是将redis执行过的所有写的指令记录下来,在reids重启之后将所有指令都执行一遍就可以恢复数据。

通过配置redis.conf的appendonly yes就可以打开AOF功能。如果有写操作(如SET等),redis就会被追加到AOF文件的末尾。

默认的AOF的持久化周期为每秒fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。

如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。

因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。

AOF方式的另一个好处,我们通过一个“场景再现”来说明。某同学在操作redis时,不小心执行了FLUSHALL,导致redis内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了。是不是很神奇,这就是AOF持久化方式的好处之一。但是如果AOF文件已经被重写了,那就无法通过这种方法来恢复数据了。

缺点:

  1. AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。

如果你直接执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最少的命令集

默认情况下,redis会异步的将数据持久化到磁盘。这种模式在大部分应用程序中已被验证是很有效的,但是在一些问题发生时,比如断电,则这种机制可能会导致数分钟的写请求丢失。

如上半部分中介绍的,追加文件(Append Only File)是一种更好的保持数据一致性的方式。即使当服务器断电时,也仅会有1秒钟的写请求丢失,当redis进程出现问题且操作系统运行正常时,甚至只会丢失一条写请求。

还可以设置aof文件的名称:

appendfilename "appendonly.aof"

fsync()调用,用来告诉操作系统立即将缓存的指令写入磁盘。一些操作系统会“立即”进行,而另外一些操作系统则会“尽快”进行。

redis支持三种不同的模式:

1.no:不调用fsync()。而是让操作系统自行决定sync的时间。这种模式下,redis的性能会最快。

2.always:在每次写请求后都调用fsync()。这种模式下,redis会相对较慢,但数据最安全。

3.everysec:每秒钟调用一次fsync()。这是性能和安全的折衷。

appendfsync everysec

四、持久化方式选择

对于我们应该选择RDB还是AOF,官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。

到这里,redis的持久化方式已经介绍完毕了,在接下来我出写一遍博文介绍redis.conf的配置文件的各个参数的作用,希望大佬给与意见,大家一起学习进步!加油!

猜你喜欢

转载自blog.csdn.net/jokeMqc/article/details/87929316