美文网首页
12.AOF持久化

12.AOF持久化

作者: xMustang | 来源:发表于2020-02-23 15:28 被阅读0次

    AOF持久化

    AOF,Append Only File

    AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。

    写入AOF文件的所有命令都是以Redis的命令请求协议格式保存。

    1. AOF持久化的实现

    AOF持久化的实现分为命令追加、文件写入、文件同步三个部分。

    1.1 命令追加

    当AOF持久化功能打开时,服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。

    struct redisServer{
        // ...
    
        // AOF缓冲区
        sds aof_buf;
    
        // ...
    }
    

    1.2 AOF文件的写入与同步

    Redis服务器进程就是一个事件循环(Loop)。

    这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复。

    这个循环中的时间事件负责执行像serverCron这样需要定时运行的函数。

    服务器在每次结束一个事件循环前,都会调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区的内容写入和保存到AOF文件里面。这个过程可以用下面伪代码表示。

    伪代码表示事件循环

    flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的值来决定,各个不同值如下图所示,默认值为everysec。

    不同appendfsync值产生不同的持久化行为

    AOF文件的写入指的是将数据写入文件,但操作系统为了提高文件的写入效率,通常会将写入数据暂时放在一个内存缓冲里。

    AOF文件的同步指的是操作系统提供fsync、fdatasync同步函数,可以强制操作系统立即将缓冲区中的数据写入到硬盘里面。

    下图是AOF持久化的效率和安全性。

    [图片上传失败...(image-dd0024-1582442941228)]

    2. AOF文件的载入与数据还原

    AOF文件包含重建数据库状态的所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的服务器状态。

    Redis读取AOF文件并还原数据库时,会创建一个不带网络连接的伪客户端。

    3. AOF重写

    为了解决AOF文件膨胀问题,Redis提供AOF文件重写。Redis服务器会创建一个新的AOF文件替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令。

    3.1 AOF文件重写的实现

    AOF文件重写不需要对现有AOF文件进行读取、分析、写入,这个功能是通过读取服务器当前的数据库状态来实现。

    AOF文件重写的原理是:从数据库中读取键现在的值,然后用一条命令记录键值对,代替之前记录这个键值对的多条命令。

    为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序在处理列表、哈希表、集合、有序集合这4种可能包含多个元素的键时,先检查键包含的元素数量,如果元素的数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD(默认值为64),那么重写程序将使用多条命令来记录键的值,而不单单使用一条命令。

    3.2 AOF后台重写

    Redis将AOF重写程序放到子进程中执行:

    1. 子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。
    2. 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。

    为了解决AOF重写时,服务器进程继续处理命令请求时,导致服务器现在状态与AOF数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建AOF子进程之后开始使用,当Redis服务器执行完一个命令后,它会同时将这个写命令发送给AOF缓冲区(aof_buf)和AOF重写缓冲区。也就是说,在子进程执行AOF重写期间,服务器进程需要执行以下三个工作:

    1. 执行客户端发来的命令。
    2. 将执行后的写命令追加到AOF缓冲区。
    3. 将执行后的写命令追加到AOF重写缓冲区。

    当子进程完成AOF重写工作后,它会向父进程发送一个信号,父进程在接到该信号后,会调用一个信号处理函数,并执行以下工作:

    1. 将AOF重写缓冲区的所有内容写入到新的AOF文件中。
    2. 对新的AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的转换。

    在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程。

    以上就是AOF后台重写,也就是BGREWRITEAOF 命令的实现原理。

    相关文章

      网友评论

          本文标题:12.AOF持久化

          本文链接:https://www.haomeiwen.com/subject/txpjqhtx.html