AOF(append only file)持久化
RDB与AOF区别:
RDB持久化是通过保存数据库中的键值对来记录数据库状态。
AOF持久化是通过报错redis服务器所执行的写命令来记录数据库状态。
频率控制
redis服务器在执行写操作时,都会追加一些内容到aof_buffer中,在结束写操作之前都会调用flushappendonlyfile函数,将buffer中的内容写入AOF文件。
flushappendonlyfile函数通过appendfsync参数,来控制同步频率。
-
appendfsync : always
//时时,特点:效率最慢,但数据最安全 -
appendfsync : everysec
//每秒钟,特点:效率高,最大可能有1秒钟内的数据丢失。 -
appendfsync : no //不同步,何时同步,由操作系统决定。特点:效率高,数据丢失可能性大。
AOF文件的载入与还原
如果redis服务器开启了AOF持久化,那么服务器会优先使用AOF还原数据。
AOF文件还原数据的过程:
1. 创建一个伪客户端。
2. 从aof文件中每一条命令。
3. 使用伪客户端执行写命令。
4. 判断aof文件是否执行完毕。
5. 载入完毕。
AOF重写
为什么要重写AOF文件?
因为aof持久化是通过保存被执行的命令来记录数据库状态,那么随着时间的推移,文件的体积会越来越大,体积过大的aof文件可能对redis服务器,甚至整个计算机造成影响,并且,如果aof文件过大,进行数据还原的时候所需要的时间也就越多。为了解决aof文件过大的问题,redis提供了重写功能。
什么是AOF重写?
就是redis服务器通过创建一个新的AOF文件来替代现有的AOF文件,新旧2个文件所保存的数据库状态是相同的,但新文件不包含任何浪费空间的冗余代码,所以新AOF文件要比旧文件小的多。
AOF重写实现原理
读取数据库中所有的键值对,然后用一条命令去记录键值对,替代之前的多条命令,这就是实现原理。
后台重写AOF文件
因为AOF重写是大量的写操作,这样会阻塞主进程,这样在重写期间就会导致redis无法响应请求。所以需要开启一个子进程去执行重写的任务。
子进程进行AOF重写期间,父进程可以继续处理命令请求。新的命令可能对现有数据状态进行修改,从而使当前数据库状态与重写后的AOF文件所保存的数据库状态不一致的问题。
如何解决以上问题?
-
redis设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当redis主进程执行一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。
-
当子进程重写完成以后,会向父进程发送一个信号,父进程接收到信号以后,会调用一个信号处理函数完成2步操作:
(1). 将AOF重写缓冲区的所有内容写到新的AOF文件中,新的AOF文件所保存的数据库状态跟服务器当前数据库状态一致。
(2). 对新的AOF文件进行改名,覆盖现有的AOF文件,完成新旧2个AOF文件的替换。
通过以上方案,将数据AOF持久化工作对主进程的阻塞时间降到了最低。
资料参考:《redis设计与实现》黄建宏注