文章目录
目录
前言
AOF是Redis持久化的另外一种策略,出厂默认no,需要手动修改为yes,RDB和AOF一起存在的时候,redis默认先载入AOF文件,如果AOF文件出错再去载入RDB文件,AOF通过将数据库所有写命令追加到AOF文件实现数据库数据的存储,AOF文件的创建过程分为三个部分,首先是命令追加,服务器会将所有的写命令追加到aof缓冲区里,然后是文件写入和文件同步阶段,当服务器的一个事件循环结束,会调用flushAppendOnlyFile函数,通过配置appendsync选项,可以实现不同的写入和同步策略,默认是everysec也就是先将aof缓冲区数据写入AOF文件,如果距离上次同步已经超过1s那就重新同步,这样最多丢失1s的数据,还有一个是every每次都同步,安全但是效率低,和no只写入同步交给操作系统,不安全但是效率高,随着时间的增长AOF文件会越变越大,超过默认大小64M时触发AOF重写,我们可以通过后台重写AOF实现高性能的AOF文件压缩,具体过程就是维持一个aof重写缓冲区,执行重写的时候子进程扫描数据库中的所有数据,每个数据通过一个或者多个添加的写命令写入到新的AOF文件,在重写过程中所有写命令同时追加到aof缓冲区和aof重写缓冲区,持久化过程结束,子进程会给服务器进程发送一个信号处理函数,服务器进程阻塞,在这期间将aof重写缓冲区内容加入到新的AOF文件,然后用新的AOF文件替换旧的AOF文件,至此完成AOF后台重写,此时新的AOF文件将不会包含任何的冗余命令信息,REWRITEAOF和BGSAVE命令不会一起执行,如果执行了REWIRTEAOF就取消BGSAVE,如果执行了BGSAVE,完成后再执行REWRITEAOF,AOF的效率和文件都比RDB大,但是更新速率快,更安全。
一、AOF(append only file)功能
- 按照Redis命令请求协议的格式保存Redis服务器所执行的写命令来记录数据库状态
二、AOF持久化的实现---AOF文件怎么写
- 命令追加 (append)
- 服务器每次执行一个写操作,就按照协议格式将这个操作追加到redisServer的aof-buf(aof缓冲区)末尾
- appendonly.aof文件写入&文件同步 (sync)
- redis服务器进程是一个事件循环,服务器每次结束一个事件循环之前会调用flushAppendOnlyFile函数,考虑是否要完成aof缓冲区中数据的文件写入和文件同步,具体如何做通过服务器配置的appendfsync选项值来决定
- appendfsync
- always
- 每次都将aof缓冲区数据写入且同步到AOF文件
- 最安全,但是效率比较低
- everysec
- 先将aof缓冲区数据写入AOF文件,如果距离上次同步已经超过1s,则再次由一个线程专门对文件进行同步
- 比较安全,只会丢失1s的数据,效率较高,默认使用它
- no
- 只将aof缓冲区数据写入AOF文件,文件同步由操作系统管理
- 最不安全,会丢失上次同步到宕机之间的数据,但是效率很
- always
- 载入AOF文件实现数据还原
- 创建一个不带网络连接的伪客户端,由它来执行AOF文件里的写命令,所有命令写完就还原出了当时的数据库状态
三、AOF重写---对AOF文件的压缩
- Redis服务器创建一个新的AOF文件,该文件不包含任何浪费空间的冗余命令,然后用它来替换之前的AOF文件
- 底层实现
- 不去扫描旧的AOF文件,直接扫描现在的数据库里有哪些数据,每一个数据通过一条SET或者SADD或者HSET或者HSET或者LPUSH命令写入到AOF文件即可,但是如果是list,set或者hash太大了,超过了默认的64,则可以通过多条SADD/HSET/LPUSH操作,每一条命令写64个实现
- 后台重写AOF
BGREWIRITEAOF- AOF重写过程比较漫长,长时间阻塞服务器进程对性能降低很大,所以引入AOF重写缓冲区,实现AOF子进程后台重写,服务器进程还可以执行其他请求
- 具体过程
- 当AOF重写子进程开始执行,服务器可以接受新的请求,且将这期间所有的写操作写入到aof缓冲区和aof重写缓冲区中
- AOF文件重写完成,子进程向服务器发送信号处理函数,信号处理函数阻塞服务器进程,然后将aof重写缓冲区里的数据追加到新的AOF文件里,然后原子的将新AOF文件更名覆盖旧的AOF文件
- 信号处理函数执行完毕,服务器进程被唤醒,接受新的请求