aof策略
🚀aof是append only file的缩写,它是记录客户端的每个操作,将这些操作写到一个文本文件中,当redis重启的时候会去读取这个aof文本文件,去恢复数据。默认情况下aof策略是关闭的,当开启aof策略的时候,当redis服务器重启的时候就不再去读取rdb文件了,而是通过aof文件去恢复数据的。
开启aof策略
🚀可以在redis的配置文件中,去开启aof持久化方案。redis的配置文件默认在/etc/redis/redis.conf 。
🚀可以看到当开启aof模式的时候,会在/var/lib/redis路径下生成aof文件:
🚀可以看到这个aof文件中确实可以看出set key 111的字样,只不过我们在客户端输入的命令在aof文件中是通过特定的格式组织起来的。
aof的缓冲区
🚀redis服务器每执行一个来自客户端的命令,都会顺带这将这个命令写入到aof的缓冲区中。这个aof缓冲区,会定期刷新到磁盘中,说白了即使是aof也不能保证记录了redis中的所有数据,因为一旦在缓冲区刷盘的过程中,服务器死机了,那么也会丢失一部分的数据。
🚀aof缓冲区的刷新策略,也可以在配置文件中配置:
🚀有三种配置,always:每条指令都会触发一次刷盘,性能较低,no:由操作系统决定刷盘的时机,性能较高,他们的这种方案为每分钟触发一次刷盘,everysec这是默认配置。总结来就是:刷新的频率越快,对性能的影响越大,数据的可靠性越高。
aof的重写机制
🚀上面简单的没执行一条命令,就追加记录到aof文件中,这会导致aof文件的体积膨胀的很大。并且其中存储了许多没有必要的命令,例如:set key 1 ,set key 2,del key ,set key 3 ,这几条命令执行下来,redis内存中其实就存储了key-3这份数据,但是aof文件中却记录了四条命令,这显然是没有必要的。
🚀aof重写就是对aof文件做整理,剔除冗余操作,合并操作。
未aof从写前:
aof重写之后:
aof重写触发机制
手动触发 | bgrewriteaof |
---|---|
自动触发 | 配置文件中:auto-aof-rewrite-min-size / auto-aof-rewrite-percentage |
🚀redis会记录最近一次aof重写之后的aof文件的大小,作为基准值。当文件目前的大小比基准值大百分之多少的时候,自动触发aof重写,但不仅仅是满足这一个条件,还要满足aof文件最小的大小为多少,避免即使满足了第一个条件的aof文件大小仍旧是很小的。
aof重写的流程
🚀服务器收到aof重写的命令的时候,会创建一个子进程去做这件事情(与rdb文件生成十分类似),子进程会把当前redis内存中的数据按照aof的格式写入到aof文件中,但是存在一个问题就是fork出的子进程只能看到fork之前的redis中的数据,因为父子进程之间会有写时拷贝的机制,所以redis服务器进程还要把接收到来自客户端的命令写入到aof-rewrite-buf中,这样最终aof文件的内容为 子进程处理的内存中的数据+aof-rewrite-buf中的数据。
🚀如果说上一个aof重写任务还没有完成,又来了个新的重写任务,那么这个任务并不会执行,并且如果aof重写任务到来的时候,发现redis的子进程正在进行rdb快照的生成,那么aof重写任务就会等待,等待rdb快照生成结束后,再进行aof重写。
🚀rdb对于fork之后来自客户端的命令产生的新数据,不去处理。aof采用的是aof-rewrite-buf来解决的。
混合持久化
🚀相比于文本文件,redis服务器重启中采用二进制文件的速度是更快的。所以又提出了混合持久化的概念,本质就是aof重写的时候写入到aof文件中的数据不在是以文本的方式写,而是以二进制的方式写。
🚀混合持久化的开启方式也是可以在配置文件中进行配置的:
🚀触发aof重写的时候是以二进制的形式写入到aof文件中的,但是重写结束后,仍然是以文本的方式追加记录到aof文件中的。当同时存在rdb和aof文件时redis以aof文件为准。