Python--Redis实战:第四章:数据安全与性能保障:第3节:AOF持久化

上一篇文章: Python--Redis实战:第四章:数据安全与性能保障:第2节:快照持久化
下一篇文章: Python--Redis实战:第四章:数据安全与性能保障:第4节:复制

AOF持久化

简单来讲,AOF持久化会将被执行的命令写到AOF文件的末尾,以此来记录数据发送的变化。所以,Redis只要从头至尾从新执行一次AOF文件包含的全部写命令,就能够恢复AOF文件所记录的数据集。AOF持久化能够经过设置代码appendonly yes配置选项来打开。编程

文件同步:在向硬盘写入文件时,至少会发生三件事情,当调用file.write()方法(或其它编程语言里面的相似操做)对文件进行写入时,写入的内容首先会被存储到缓冲区,而后操做系统会在未来的某个时候将缓冲区存储的内容写入硬盘,而数据只有在被写入硬盘后,才算是真正地保存到了硬盘里面。用户能够经过调用file.flush()方法来请求操做系统尽快地将缓冲区存储的数据写入硬盘里面,但具体地执行写入操做仍然由系统决定。除此以外,用户还能够命令操做系统将文件同步(sync)到硬盘,同步操做会一直阻塞直到指定的文件被写入硬盘为止。当同步操做执行完毕以后,即便系统出现故障也不会对被同步的文件形成任何影响。

下表展现了appendfsync 配置选项对AOF文件的同步频率的影响。segmentfault

选项 同步频率
always 每一个Redis写命令都要同步写入硬盘。这样作会严重下降Redis的速度。
everysec 每秒执行一次同步,显示地将多个写命令同步到硬盘。
no 让操做系统来决定应该什么时候进行同步。

若是用户使用appendfsync always 选项的话,那么每一个Redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少。不过遗憾的是,由于这种同步策略须要对硬盘进行大量写入,因此Redis处理命令的速度会受到硬盘性能的限制:转盘式硬盘(spinning disk)在这种同步频率下每秒只能处理大约200个写命令,而固态硬盘(solid-state drive,SSD)每秒大概也只能处理几万个写命令。安全

警告:固态硬盘和appendfsync always

使用固态硬盘的用户请谨慎使用appendfsync always选项,由于这个选项让Redis每次只写入一个命令,而不是像其余appendfsync选项那样一次写入多个命令,这种不断地写入少许数据的作法有可能会引起严重的写入放大(write amplification)问题,在某些环境下甚至会将固态硬盘的寿命从原来的几年下降为几个月。服务器

为了兼顾数据安全和写入性能,用户能够考虑使用appendfsync everysec选项,让Redis以每秒一次的频率对AOF文件进行同步。Redis每秒同步一次AOF文件时的性能和不使用任何持久化特性时的性能相差无几,而经过每秒同步一次AOF文件,Redis能够保证,即便出现系统崩溃,用户也最多只会丢失一秒以内产生的数据。当硬盘忙于执行写入操做的时候,Redis还会优雅地放慢本身的速度以便适应硬盘的最大写入速度。app

最后,若是用户使用appendfsync no选项,那么Redis将不对AOF文件执行任何显示的同步操做,而是由操做系统来决定应该在什么时候对AOF文件进行同步。这个选项在通常状况下不会对Redis的性能带来影响,但系统崩溃将致使使用这种选项的Redis服务器丢失不定数量的数据。另外,若是用户的硬盘处理写入操做的速度不够快的话,那么当缓冲区被等待写入磁盘的数据填满时,Redis的写入操做将被阻塞,并致使Redis处理命令请求的速度变慢。由于这个缘由,通常来讲并不推荐使用appendfsync no选项,在这里介绍了它只是为了完整列举appendfsync选项的可用的3个值。编程语言

虽然AOF持久化很是灵活地提供了多种不一样的选项来知足不一样应用程序对数据安全的不一样要求,但AOF持久化也有缺陷:那就是AOF文件的体积大小。性能

重写、压缩AOF文件

AOF持久化既能够将丢失数据的时间区间下降至1秒(甚至不丢失任何数据),又能够在极端的时间内完成按期的持久化操做,那么咱们有什么理由不使用AOF持久化呢?可是这个问题实际上并无那么简单,由于Redis会不断地将被执行的写命令记录到AOF文件里面,全部随着Redis不断运行,AOF文件的体积会不断增加,在极端状况下,体积不断增大的AOF文件甚至可能会用完磁盘的全部可用空间。还有另外一个问题是,由于Redis在重启以后须要经过从新执行AOF文件记录的全部写命令的还原数据集,因此若是AOF文件的体积很是大,那么还原操做执行的时间就可能会非诚长。操作系统

为了解决AOF文件体积不断增大的问题,用户能够向Redis发送bgrewriteaof命令,这个命令会经过移除AOF文件中的冗余命令来重写(rewrite)AOF文件,使AOF文件的体积变得尽量地小。bgrewriteaof的工做原理和bgsave建立快照的工做缘由很是类似:Redis会建立一个子进程,而后由子进程负责对AOF文件进行重写。由于AOF文件重写也须要用到子进程,因此快照持久化由于建立子进程而致使的性能问题和内存占用问题,在AOF持久化中也一样存在。更糟糕的是,若是不加以控制的话,AOF文件的体积可能会比快照的体积大好几倍,在进行AOF重写并删除旧AOF文件的时候,删除一个体积达到数十GB大的旧AOF文件可能会致使操做系统挂起数秒。进程

跟快照持久化能够经过设置save选项来自动执行bgsave同样,AOF持久化也能够经过设置auto-aof-rewrite-percentage选项和auto-aof-rewrite-min-size选项来自动执行bgrewriteaof。举个例子,假设用户对Redis设置了配置选项auto-aof-rewrite-percentage 100和auto-aof-rewrite-min-size 64mb,而且启用了AOF持久化,那么当AOF文件的体积大于64MB,而且AOF文件的体积比上一次重写以后的体积大了至少一倍(100%)的时候,Redis将执行bgrewriteaof命令。若是aof重写执行得过于频繁地话,那么用户能够考虑将auto-aof-rewrite-percentage选项的值设置为100以上,这种作法可让Redis在AOF文件的体积变得更大以后才执行重写操做,不过也会让Redis在启动时还原数据集所需的时间变得更长。内存

不管是使用AOF持久化仍是快照持久化,将数据持久化到硬盘上都是很是有必要的,但除了进行持续化以外,用户还必须对持久化所得的文件进行备份(最好是备份到不一样的地方),这样才能尽可能避免数据丢失事故发生。若是条件容许的话,最好可以将快照文件和最新重写的AOF文件备份到不一样的服务器上面。

经过使用AOF持久化或者快照持久化,用户能够在系统重启或者崩溃的状况下仍让保留数据。随着负载量的上升、或者数据的完整性变得愈来愈重要时,用户可能须要使用复制性。

上一篇文章: Python--Redis实战:第四章:数据安全与性能保障:第2节:快照持久化
下一篇文章: Python--Redis实战:第四章:数据安全与性能保障:第4节:复制
相关文章
相关标签/搜索