AOF(append of only)相似于MySQL的binlog,是将redis操作的指令做为日志保留到文件中,做为数据的备份。应用该文件能够重放所有时刻的内存数据,当然也能够复原到最新的数据状态。
AOF保留的默认文件名为dump.aof,能够通过配置批改文件名称

appendfilename appendonly.4379.aof

Redis的默认状态是敞开AOF的长久化性能的,应用配置开启

appendonly yes

在AOF性能开启后,Redis启动时会优先应用aof文件复原内存,这是因为AOF的数据绝对于RDB数据保留的更残缺一些,这个咱们前面会详情介绍。

AOF长久化实现

Redis在执行完写命令时,会将执行命令以一种协定的形式写入到aof文件中。Redis对命令的长久化提供了三种模式:AOF_FSYNC_NO、AOF_FSYNC_EVERYSEC和 AOF_FSYNC_ALWAYS。
Redis在写文件的时候,操作系统内核会开启一个缓冲区buffer,文件写入缓存区,当缓冲区已满时,操作系统会刷新buffer真正的写入到磁盘。程序也能够强制刷新缓冲区来将数据刷到磁盘上。依据这个机制,咱们看一下Redis的三种长久化模式的区别。

  • AOF_FSYNC_ALWAYS 每接管一个写操作都进行一次长久化,即先执行write()函数,写入操作系统的缓冲区,而后再调用fsync将数据同步到磁盘上。
    Always模式尽管保障了数据的安全性,但频繁的IO也会减少磁盘的压力,从而升高Redis的整体效率。
  • AOF_FSYNC_NO Redis不会被动进行fsync操作,只会将数据写入到缓冲区,由操作系统来管制是否写入磁盘。刷盘的操作在以下三种状况下会被触发:
    AOF性能被敞开
    Redis服务敞开
    超过30秒(操作系统默认是30秒刷新一次缓存区)或操作系统缓冲区已满
    这种形式升高了IO频繁刷盘的压力,但数据安全性上会存在一些问题,服务宕机时有可能造成一个缓冲区大小的数据失落。
  • AOF_FSYNC_EVERYSEC 联合下面两种模式做了折中,每秒都会进行一次刷盘的操作,从数据安全性上和IO压力上进行了均衡。
    Redis主过程会调用fork()函数生成一个子过程,用于aof文件的存盘解决。子过程会每隔一秒钟执行一次fsync同步文件到磁盘,在执行fsync时,存在三种状况
    如果子过程正在进行save磁盘操作,且执行工夫小于2秒钟时,flushAppendOnlyFile会立刻返回;
    当子过程执行save的工夫超过2秒钟时,则只会执行写入缓冲区操作。但此时写入缓冲区依然会阻塞期待之前的save执行结束能力进行,而后接着执行新的save操作;
    以后子过程没有执行SAVE操作,此时须要看间隔最近一次save胜利的工夫距离,如果大于1秒,则间接执行write,并执行save。小于1秒时则只进行write操作。
    从下面的过程来看Redis失落的数据有可能在2秒以上。EVERYSEC模式兼顾了安全性和性能,适应大多数的利用场景,生产上个别也会应用这种模式。
appendfsync everysec#appendfsync aways#appendfsync no

AOF文件重写

随着Redis运行工夫的减少,aof文件会变的越来越大,redis提供了从新的性能来防止文件过大而产生性能问题。
AOF重写时也利用的写时复制机制,

  • 调用fork()函数取得一个子过程,并和父过程共享内存数据
  • 子过程将内存数据转化成对应的命令协定数据,写入长期aof文件;同时父过程会开拓一块内存缓存区,接管新的写操作。在此过程中父过程仍然会向现有的aof文件追加操作指令,以保障以后的aof文件可用性
  • 子过程重写结束后,父过程会失去一个信号,将重写过程中接管到的写入操作追加到长期aof文件开端
  • 将aof文件切换到新的文件上

在redis4.0版本之后,反对采纳RDB和AOF的混合模式进行重写。Redis先将内存数据已RDB的形式写入到AOF文件中,而后再将新增的写操作命令追加到文件开端。在redis进行内存加载时,当读取到文件以REDIS为结尾的数据时,就做为RDB的模式进行内存复原,而后对前面增量的AOF命令数据进行执行即可。这样即利用了RDB占用空间小和复原快的长处,还兼顾AOF数据存储实时的个性。
配置文件中这样开启

aof-use-rdb-preamble yes

AOF重写触发机制

redis中提供了BGREWRITEAOF命令来手动执行aof的重写。在配置文件能够通过如下配置来管制主动触发

auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb

Redis每次rewrite之后会记录下来aof文件的大小,当aof文件大小大于64M并且超过了上次重写完的文件大小值的100%时,主动进行一次rewrite操作。