Redis持久化AOF

Posted 一颗心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis持久化AOF相关的知识,希望对你有一定的参考价值。

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 100
auto-aof-rewrite-min-size 64mb

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

以上是关于Redis持久化AOF的主要内容,如果未能解决你的问题,请参考以下文章

redis 之redis持久化rdb与aof

redis学习--redis的AOF持久化相关配置和操作

Redis持久化--AOF

Redis---- Redis的持久化机制RDB和AOF原理

Redis---- Redis的持久化机制RDB和AOF原理

Redis---- Redis的持久化机制RDB和AOF原理