使用快照和AOF将Redis数据持久化到硬盘中

前言

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

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

还有一些场景,例如:

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

Redis给我们提供了两种不同方式的持久化方法:快照(Snapshotting)只追加文件(append-only-file)

(1)名词简介

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

只追加文件(AOF):他会在执行写命令的时候,将执行的写命令复制到硬盘里面,后期恢复的时候,只需要重新执行一下这个写命令就可以了。类似于我们的MySQL数据库在进行主从复制的时候,使用的是binlog二进制文件,同样的是执行一遍写命令;

(2)快照持久化通用的配置:

(3)AOP持久化配置:

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

快照持久化

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

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

一、创建快照的方式:

(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命令之后关闭服务器。

二、使用快照持久化注意事项:

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

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

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

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

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

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

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

AOF持久化

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

一、打开AOF持久化选项

我们可以通过使用如下命令打开AOF:

appendonly yes

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

appendfsync everysec/always/no

二、appendfsync同步频率的区别

appendfsync同步频率的区别如下图:

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

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

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

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

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

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

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

三、重写/压缩AOF文件

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

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

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

四、触发重写/压缩AOF文件条件设定

AOF通过设置auto-aof-rewrite-percentageauto-aof-rewrite-min-size 选项来自动执行BGREWRITEAOF。

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

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

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

验证快照文件和AOF文件

无论使用哪种方式进行持久化,我们在进行恢复数据的时候,Redis提供了两个命令行程序:

redis-check-aofredis-check-dump

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

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

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

总结

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


参考文章:

1、Redis in Action - [美] Josiah L.Carlsono

版权声明

Java后端技术所推送文章,为本人原创、网上收集或其他作者投稿,对于网上收集部分除非确实无法确认,我们都会注明作者和来源。部分文章推送时未能与原作者取得联系。若涉及版权问题,烦请原作者联系我们,我们会在24小时内删除处理,谢谢!^_^ QQ:1573876303。

原文发布于微信公众号 - Java后端技术(JavaITWork)

原文发表时间:2017-03-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jerry的SAP技术分享

如何找到SAP Cloud for Customer标准培训和认证方面的信息

有一些朋友询问我如何在SAP官网上找到和SAP Cloud for Customer相关的标准培训信息,我这里把步骤写出来:

11310
来自专栏ImportSource

教你看懂redis配置系列

摘要:最近工作中需要开发redis的一个云管理平台。所以要求要对这些参数了如指掌,特结合网络资料和自己翻译小撸此文。感谢junjie 【 简介】 我们可以在启动...

51090
来自专栏北京马哥教育

浅谈小白如何读懂Redis高速缓存与持久化并存及主从高可用集群

一、简介 Redis是一个基于键值(K-V)的高速缓存软件,和他具有相同功能的软件有memcached,但其支持更为复杂的数据结构,例如:List,set,s...

44770
来自专栏哲学驱动设计

信息系统开发平台OpenExpressApp - ClickOnce智能部署

    这里讲的是OpenExpressApp的部署方案。主要使用的是ClickOnce作为实施方案来实现:智能部署和智能客户端。不过,这里的使用方式跟以往的不...

24450
来自专栏容器云生态

redis超时原因排查

1.低效操作产生的延迟。单命令操作一半很快不会造成这样,SORT,LREM, SUNION,keys ,* 等操作都会影响响应时间。 使用进程监控程序(top,...

1K60
来自专栏java一日一条

redis的持久化方式RDB和AOF的区别

最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据。由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需...

20060
来自专栏王亚昌的专栏

【zookeeper】安装指南

http://www.apache.org/dyn/closer.cgi/zookeeper/

9720
来自专栏我和PYTHON有个约会

Django来敲门~第一部分【6.1 视图函数】

在我们创建好的应用polls/中,可以定义视图函数,专门用于接收和响应URL请求操作的函数; 该函数默认第一个参数接收的就是一个请求对象HttpRequest...

8010
来自专栏技术博文

linux定时任务的设置

为当前用户创建cron服务 1.  键入 crontab  -e 编辑crontab服务文件       例如 文件内容如下:      */2 * * * *...

1.7K100
来自专栏个人分享

MongoDB 3.0 导入命令

./mongoimport -h 192.168.77.129 --db test --collection restaurants --drop --file...

9910

扫码关注云+社区

领取腾讯云代金券