本文转自互联网git
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到个人仓库里查看github
喜欢的话麻烦点下Star哈redis
文章首发于个人我的博客:数据库
www.how2playlife.com缓存
本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部份内容来源于网络,为了把本文主题讲得清晰透彻,也整合了不少我认为不错的技术博客内容,引用其中了一些比较好的博客文章,若有侵权,请联系做者。安全
该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也须要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及做为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,造成本身的知识框架。服务器
若是对本系列文章有什么建议,或者是有什么疑问的话,也能够关注公众号【Java技术江湖】联系做者,欢迎你参与本系列博文的创做和修订。微信
咱们知道Redis是一款内存服务器,就算咱们对本身的服务器足够的信任,不会出现任何软件或者硬件的故障,但也会有可能出现忽然断电等状况,形成Redis服务器中的数据失效。所以,咱们须要向传统的关系型数据库同样对数据进行备份,将Redis在内存中的数据持久化到硬盘等非易失性介质中,来保证数据的可靠性。网络
将Redis内存服务器中的数据持久化到硬盘等介质中的一个好处就是,使得咱们的服务器在重启以后还能够重用之前的数据,或者是为了防止系统出现故障而将数据备份到一个远程的位置。
还有一些场景,例如:
对于一些须要进行大量计算而获得的数据,放置在Redis服务器,咱们就有必要对其进行数据的持久化,若是须要对数据进行恢复的时候,咱们就不需进行从新的计算,只须要简单的将这台机器上的数据复制到另外一台须要恢复的Redis服务器就能够了。
Redis给咱们提供了两种不一样方式的持久化方法:快照(Snapshotting) 和 只追加文件(append-only-file)。
(1)名词简介
快照(RDB):就是咱们俗称的备份,他能够在按期内对数据进行备份,将Redis服务器中的数据持久化到硬盘中;
只追加文件(AOF):他会在执行写命令的时候,将执行的写命令复制到硬盘里面,后期恢复的时候,只须要从新执行一下这个写命令就能够了。相似于咱们的MySQL数据库在进行主从复制的时候,使用的是binlog
二进制文件,一样的是执行一遍写命令;
(2)快照持久化通用的配置:
save 60 1000 #60秒时间内有1000次写入操做的时候执行快照的建立stop-writes-on-bgsave-error no #建立快照失败的时候是否仍然继续执行写命令rdbcompression yes #是否对快照文件进行压缩dbfilename dump.rdb #如何命名硬盘上的快照文件dir ./ #快照所保存的位置
(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所保存的位置
须要注意的是:这两种持久化的方式既能够单独的使用,也能够同时使用,具体选择哪一种方式须要根据具体的状况进行选择。
快照就是咱们所说的备份。用户能够将Redis内存中的数据在某一个时间点进行备份,在建立快照以后,用户能够对快照进行备份。一般状况下,为了防止单台服务器出现故障形成全部数据的丢失,咱们还能够将快照复制到其余服务器,建立具备相同数据的数据副本,这样的话,数据恢复的时候或者服务器重启的时候就可使用这些快照信息进行数据的恢复,也能够防止单台服务器出现故障的时候形成数据的丢失。
可是,没咱们还须要注意的是,建立快照的方式,并不能彻底保证咱们的数据不丢失,这个你们能够很好的理解,由于快照的建立时定时的,并非每一次更新操做都会建立一个快照的。系统发生崩溃的时候,用户将丢失最近一次生成快照以后更改的全部数据。所以,快照持久化的方式只适合于数据不常常修改或者丢失部分数据影响不大的场景。
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、使用快照持久化注意事项:
咱们在使用快照的方式来保存数据的时候,若是Redis服务器中的数据量比较小的话,例如只有几个GB的时候。Redis会建立子进程并将数据保存到硬盘里边,生成快照所需的时间比读取数据所须要的时间还要短。
可是,随着数据的增大,Redis占用的内存愈来愈大的时候,BGSAVE在建立子进程的时候消耗的时间也会愈来愈多,若是Redis服务器所剩下的内存很少的时候,这行BGSAVE命令会使得系统长时间地停顿,还有可能致使服务器没法使用。
各虚拟机类别,建立子线程所耗时间:
所以,为了防止Redis由于建立子进程的时候出现停顿,咱们能够考虑关闭自动保存,转而经过手动的方式发送BGSAVE或者SAVE来进行持久化,
手动的方式发送BGSAVE也会出现停顿的现象,可是咱们能够控制发送该命令的时间来控制出现停顿的时候不影响具体的业务请求。
另外,值得注意的是,在使用SAVE命令的时候,虽然会一直阻塞Redis直到快照生成完毕,可是其不须要建立子进程,因此不会向BGSAVE同样,由于建立子进程而致使Redis停顿。也正由于如此,SAVE建立快照的速度要比BGSAVE建立快照的速度更快一些。
建立快照的时候,咱们能够在业务请求,比较少的时候,好比凌晨3、四点,经过手写脚本的方式,定时执行。
AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。这样,咱们在恢复数据的时候,只须要从头至尾的执行一下AOF文件便可恢复数据。
1、打开AOF持久化选项
咱们能够经过使用以下命令打开AOF:
appendonly yes
咱们,经过以下命令来配置AOF文件的同步频率:
appendfsync everysec/always/no
2、appendfsync同步频率的区别
appendfsync同步频率的区别以下图:
(1)always的方式当然能够对没一条数据进行很好的保存,可是这种同步策略须要对硬盘进行大量的写操做,因此Redis处理命令的速度会受到硬盘性能的限制。
普通的硬盘每秒钟只能处理大约200个写命令,使用固态硬盘SSD每秒能够处理几万个写命令,可是每次只写一个命令,这种只能怪不断地写入不多量的数据的作法有可能引起严重的写入放大问题,这种状况降低严重影响固态硬盘的使用寿命。
(2)everysec的方式,Redis以每秒一次的频率大队AOF文件进行同步。这样的话既能够兼顾数据安全也能够兼顾写入性能。
Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性时的性能相差无几,使用每秒更新一次 的方式,能够保证,即便出现故障,丢失的数据也在一秒以内产生的数据。
(3)no的方式,Redis将不对AOF文件执行任何显示的同步操做,而是由操做系统来决定应该什么时候对AOF文件进行同步。
这个命令通常不会对Redis的性能形成多大的影响,可是当系统出现故障的时候使用这种选项的Redis服务器丢失不定数量的数据。
另外,当用户的硬盘处理写入操做的速度不够快的话,那么缓冲区被等待写入硬盘的数据填满时,Redis的写入操做将被阻塞,并致使Redis处理命令请求的速度变慢,由于这个缘由,通常不推荐使用这个选项。
3、重写/压缩AOF文件
随着数据量的增大,AOF的文件可能会很大,这样在每次进行数据恢复的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户能够向Redis发送BGREWRITEAOF
命令,这个命令会经过移除AOF文件中的冗余命令来重写AOF文件,是AOF文件的体检变得尽量的小。
BGREWRITEAOF的工做原理和BGSAVE的原理很像:Redis会建立一个子进程,而后由子进程负责对AOF文件的重写操做。
由于AOF文件重写的时候汇建立子进程,因此快照持久化由于建立子进程而致使的性能和内存占用问题一样会出如今AOF文件重写的 时候。
4、触发重写/压缩AOF文件条件设定
AOF经过设置auto-aof-rewrite-percentage
和 auto-aof-rewrite-min-size
选项来自动执行BGREWRITEAOF。
其具体含义,经过实例能够看出,以下配置:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
表示当前AOF的文件体积大于64MB,而且AOF文件的体积比上一次重写以后的体积变大了至少一倍(100%)的时候,Redis将执行重写BGREWRITEAOF命令。
若是AOF重写执行的过于频繁的话,能够将auto-aof-rewrite-percentage
选项的值设置为100以上,这种最偶发就可让Redis在AOF文件的体积变得更大以后才执行重写操做,不过,这也使得在进行数据恢复的时候执行的时间变得更加长一些。
不管使用哪一种方式进行持久化,咱们在进行恢复数据的时候,Redis提供了两个命令行程序:
redis-check-aofredis-check-dump
他们能够再系统发生故障的时候,检查快照和AOF文件的状态,并对有须要的状况对文件进行修复。
若是用户在运行redis-check-aof命令的时候,指定了--fix
参数,那么程序将对AOF文件进行修复。
程序修复AOF文件的方法很简单:他会扫描给定的AOF文件,寻找不正确或者不完整的命令,当发现第一个出现错误命令的时候,程序会删除出错命令以及出错命令以后的全部命令,只保留那些位于出错命令以前的正确命令。大部分状况,被删除的都是AOF文件末尾的不完整的写命令。
上述,一块儿学习了两种支持持久化的方式,一方面咱们须要经过快照或者AOF的方式对数据进行持久化,另外一方面,咱们还须要将持久化所获得的文件进行备份,备份到不一样的服务器上,这样才能够尽量的减小数据丢失的损失。
参考文章:
一、Redis in Action - [美] Josiah L.Carlsono