- AOF保存的服务器所执行的写命令(set,del,add 等)来记录状态的
-
文件保存的是存文本 ,且都按照redis的命令请求协议保存格式的,具体如下
- AOF持久化功能实现分为命令追加(append),文件写入,文件同步sync三个步骤。
append
- 服务器在执行完一个写命令之后,会以协议格式 将被执行的写命令追求服务器状态的aof_buf缓冲区的末尾
AOF文件的写入与同步
-
redis每次追加完内容到aof_buf缓冲后会调用flushAppendOnlyFile函数,
-
flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的
-
aof 持久化的效率和安全性
文件写入就是写入到页中,同步则是从页到磁盘。
everysec 原则上每隔一秒钟就会执行一次, 因为 SAVE 操作是由后台子线程调用的, 所以它不会引起服务器主进程阻塞。
AOF 文件的载入与数据还原
-
伪客户端是一个不带网络连接的客户端
AOF 重写
因为AOF 文件会越来越多,这回导致 我们还原AOF文件所需要很多时间。
通过合并命令(删除无用的命令比如之前add 了一条后有一个del 就可以了)
新建一个AOF 替代老的文件
-
其原理:比如我们对键进行了6次操作 记录到老的aof文件,重写则是获取list的值,直接 用一个命令替代之前的多个命令,所以重写不需要读取aof文件具体原理如下(即我们先调用get命令,改命令不会增加命令日志,然后在调用对应的对象set方法 重写写该key的值,而该命令就会被写入新的文件,为了避免key对应的内容太多导致客户端的输入缓冲区溢出,太多的数据我们还是会分批重写):
上述重写的方法会调用对应的set方法导致方法线程被阻塞(因为key太多),所以我们采用后台进程去写,
使用进程而不是线程是因为进程可以携带服务器的副本数据,而不用和主进程的线程进行锁的冲突,但是这就会导致数据不一致(因为这个时候主进程还在进行其他命令操作)为了解决上述问题(我们重写使用后台进程,现有的AOF都在主进程进行,只是save 可以启动子线程进行save)我们创建了AOF缓冲区和AOF重写缓冲区,分别把执行完的写命令写到这两个缓冲区
子进程完成重写工作后会给主进程发送信号,会执行以下步骤:将重写缓冲区的命令都写入重写文件,对新的aof文件改名并原子的替换旧的文件,父进程需要暂停其他命令去完成这个操作 然后后续正常工作