AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。被写入AOF文件的所有命令都是以Redis的命令请求协议格式(纯文本)保存的。

一,AOF持久化的实现

1.命令追加

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

struct redisServer{

  //AOF缓冲区

  sds aof_buf;

}

2.AOF文件的写入和同步

命令请求会先保存到AOF缓冲区中,然后在写入并同步到AOF文件。

Redis服务器进程是一个事件循环,在这个循环中有文件事件,有时间事件。文件事件负责接收客户端的命令请求和向客户端发送命令回复。时间事件负责执行定时运行的函数,比如:serverCron函数。

伪代码:

def eventLoop():

  while true:

    //处理文件事件,接收命令请求以及发送命令回复。处理命令请求时可能会有新内容被追加到aof_buf缓冲区中

    processFileEvents()

    //处理时间事件

    processTimeEvents()

    //考虑是否要把 aof_buf中的内容写入和保存到AOF文件中

    flushAppendOnlyFile()

写入:在现代操作系统中,当数据写入到文件中时,会调用write函数。操作系统会将写入数据暂时保存在一个内存缓存区中,等到缓冲区空间满的时候,才真正将缓冲区中的数据写入到磁盘中。

同步:同时系统也提供了同步函数,它可以强制让操作系统立即将缓冲区中的数据写入到磁盘中。

由上面的代码可以知道,在每个事件循环都会调用flushAppendOnlyFile函数,flushAppendOnlyFile函数的行为由appendfsync的值决定:

always:服务器在每个事件循环都要将aof_buf缓冲区中的所有内容写入到AOF文件中,并同步AOF文件(写入并同步)(,把aof_buf数据写入并同步到AOF文件中)

everysec:服务器在每个事件循环都要将aof_buf缓冲区中的所有内容写入到AOF文件中(先写入),并且每隔一秒就在子线程中对AOF文件进行一次同步(每隔一秒同步)。

no:服务器在每个事件循环都要将aof_buf缓冲区中的所有内容写入到AOF文件中(先写入),至于什么时候同步,由操作系统控制(不知道啥时候同步)。在该模式下的flushAppendOnlyFile的调用不需要同步执行。

二,AOF文件的载入和数据还原

1.数据还原:AOF文件中包含了重建数据库状态的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里保存的写命令,就可以还原数据

2.步骤:

创建一个不带网络连接的伪客户端。(为什么是为客户端:Redis的命令只能在客户端上下文中执行,为什么是不带网络连接:命令来自AOF文件而不是网络连接)

从AOF文件中分析并读取一条写命令

使用伪客户端执行被读出的写命令

一直执行步骤2,3 。直到AOF文件中的所有写命令都被处理完毕

三,AOF重写

1.什么是AOF重写?

为了解决AOF文件体积膨胀,Redis服务器创建一个新的AOF文件替代现有的AOF文件,新旧两个文件保存的数据库状态相同,但是新AOF文件不会包含冗余命令。

Redis把新AOF文件替换旧AOF文件的功能叫 AOF文件重写。

2.AOF文件重写的实现

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

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

【如果服务器想要用尽量少的命令来记录键的状态,那么最简单的办法不是去读取和分析现有AOF文件的内容,而是直接从数据库中读取键的值,然后用一条写命令来替代保存在AOF文件中的多条写命令,这样就可以把保存键的多条命令减少为一条。】

在实际中,为了避免在执行命令时造成客户端输入缓冲区溢出。在处理有多个元素的键时,会先检查键包含的元素数量,如果超过了一定的值,会使用多条命令来记录键的值。比如一个列表键包含了超过64个项,那么重写程序会用多条rpush命令来保存这个列表。

3.AOF后台重写

问题:由于Redis服务器使用单个线程处理命令请求,当服务器调用aof_rewrite函数时,在重写AOF文件期间,服务器无法处理客户端发送来的命令请求

解决:把AOF重写程序放到子进程中执行,这样子进程重写期间,父进程可以继续处理命令请求。并且子进程带有父进程的数据副本。

那么问题又来了:在子进程进行AOF重写期间,服务器进程在处理命令请求时可能会改变数据库状态,导致服务器当前数据库状态和重写后的AOF文件保存的数据库状态不一致

为了解决数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在创建子进程之后使用,当Redis服务器执行完一个写命令后,会同时把这个写命令发送给AOF缓冲区和AOF重写缓冲区。

在子进程执行AOF重写期间,服务器需要:

执行客户端发送过来的命令

将执行后的写命令追加到AOF缓冲区

将执行后的写命令追击到AOF重写缓冲区

当子进程完成重写工作后,向父进程发送一个信号,父进程在接到这个信号后,把AOF重写缓冲区中的所有内容写到新AOF文件中,并对新的AOF文件进行改名,覆盖现有的AOF文件。

第二部分之AOF持久化(第十一章)的更多相关文章

  1. 第二部分之RDB持久化(第十章)

    RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态.(数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态) 一.RDB文件的创建 ...

  2. o'Reill的SVG精髓(第二版)学习笔记——第十一章

    第十一章:滤镜 11.1滤镜的工作原理 当SVG阅读器程序处理一个图形对象时,它会将对象呈现在位图输出设备上:在某一时刻,阅读器程序会把对象的描述信息转换为一组对应的像素,然后呈现在输出设备上.例如我 ...

  3. 第二部分之Redis服务器(第十四章)

    Redis服务器复制和多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据. 一,命令请求的执行过程 客户端向服务器发送命令请求 set key value 服务 ...

  4. JavaScript高级程序设计:第二十一章

    第二十一章 Ajax与Comet 一.XMLHttpRequest对象 1.XHT的用法 在使用XHR对象时,要调用的第一个方法时open( ),它接受3个参数:要发送的请求的类型.请求的URL和表示 ...

  5. 第二十一章 Django的分页与cookie

    第二十一章 Django的分页与cookie 第一课 模板 1.模板的继承 在Template目录下新建模板master.html <!DOCTYPE html> <html lan ...

  6. Gradle 1.12用户指南翻译——第二十一章. Gradle 插件

    昨天晚上只顾着和女朋友看<匆匆那年>电视剧的最后几集,所以说好的Android文档<Gradle 插件用户指南>第五章自然也没翻译多少.所以今天也发不了第五章的翻译了,就发几个 ...

  7. “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  8. “全栈2019”Java异常第二十一章:finally不被执行的情况

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  9. “全栈2019”Java第二十一章:流程控制语句中的决策语句if

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. 别的C#基础笔记

    1.方法名称             *  规范:每一个单词的首字母大写 2.方法的返回值 *  void:没有返回值.不能使用return来返回具体的值 ,但是可以使用return终止当前方法    ...

  2. C# Quartz定时任务corn时间设置详解

    http://cron.qqe2.com/  如果不会 或者想检验自己是否写的对就  通过这个网站 检测 或自动生成 *    *         *     *      *      *      ...

  3. PhpStorm 安装ApiDebugger

    ApiDebugger,是一个开源的接口调试IntelliJ IDEA插件,具有与IDEA一致的界面,无需切换程序即可完成网络API请求,让你的code更加沉浸式. 安装 File->Setti ...

  4. 配置javaJDK环境

    1.官网下载JDK包 2.解压包 3.打开vi /etc/profile文件添加一下内容 export JAVA_HOME=/usr/jdk1.8.0_121 #你的jdk所在的目录 export C ...

  5. 移动端web自适应适配布局解决方案

    100%还原设计图,要注意: 看布局,分析结构. 感觉难点在于: 1.测量精度(ps测量数据): 2.文字的行高. 前段时间写个移动端适配的页面(刚接触这方面),查了一些资料,用以下方法能实现: 1. ...

  6. JavaScript面试总结(一)

    (一).call,apply,bind 的用法与区别? 答案:摘自:https://www.cnblogs.com/Jade-Liu18831/p/9580410.html(总结的特别棒的一篇文章) ...

  7. JAVA程序员学PHP

    工作之余,趁着五一假期学习下PHP,都说PHP是世界上最美的语言,而且现在应用的有这么广泛,在短期时间内在编程的市场上打得火热,好奇心趋势我去学习一下,下面便是我学习PHP记录下来的过程,和大家分享一 ...

  8. ccflow表机构与运行机制(二次开发必看)

    驰骋工作流引擎,工作流程管理系统,表结构与运行机制. ------------------------------------------------------- 前言: 1, ccflow 有自动 ...

  9. ASP.NET Core 一步步搭建个人网站(1)_环境搭建

    ASP.NET Core2.0发布有一阵子了,这是.NET 开源跨平台的一个重大里程碑, 也意味着比1.0版本要更加成熟.目前.net core具有开源.跨平台.灵活部署.模块化架构等等特性,吸引着一 ...

  10. java之日志管理

    一. 为什么要使用日志 二. 常见日志框架介绍 三. Logback+SLF4J实战 四. 项目源码下载 五. 参考文章   一. 为什么要使用日志 1. 对IT安全至关重要   当您使用强大的日志管 ...