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原理