第二部分之AOF持久化(第十一章)
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持久化(第十一章)的更多相关文章
- 第二部分之RDB持久化(第十章)
RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态.(数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态) 一.RDB文件的创建 ...
- o'Reill的SVG精髓(第二版)学习笔记——第十一章
第十一章:滤镜 11.1滤镜的工作原理 当SVG阅读器程序处理一个图形对象时,它会将对象呈现在位图输出设备上:在某一时刻,阅读器程序会把对象的描述信息转换为一组对应的像素,然后呈现在输出设备上.例如我 ...
- 第二部分之Redis服务器(第十四章)
Redis服务器复制和多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据. 一,命令请求的执行过程 客户端向服务器发送命令请求 set key value 服务 ...
- JavaScript高级程序设计:第二十一章
第二十一章 Ajax与Comet 一.XMLHttpRequest对象 1.XHT的用法 在使用XHR对象时,要调用的第一个方法时open( ),它接受3个参数:要发送的请求的类型.请求的URL和表示 ...
- 第二十一章 Django的分页与cookie
第二十一章 Django的分页与cookie 第一课 模板 1.模板的继承 在Template目录下新建模板master.html <!DOCTYPE html> <html lan ...
- Gradle 1.12用户指南翻译——第二十一章. Gradle 插件
昨天晚上只顾着和女朋友看<匆匆那年>电视剧的最后几集,所以说好的Android文档<Gradle 插件用户指南>第五章自然也没翻译多少.所以今天也发不了第五章的翻译了,就发几个 ...
- “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第二十一章:finally不被执行的情况
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java第二十一章:流程控制语句中的决策语句if
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- 别的C#基础笔记
1.方法名称 * 规范:每一个单词的首字母大写 2.方法的返回值 * void:没有返回值.不能使用return来返回具体的值 ,但是可以使用return终止当前方法 ...
- C# Quartz定时任务corn时间设置详解
http://cron.qqe2.com/ 如果不会 或者想检验自己是否写的对就 通过这个网站 检测 或自动生成 * * * * * * ...
- PhpStorm 安装ApiDebugger
ApiDebugger,是一个开源的接口调试IntelliJ IDEA插件,具有与IDEA一致的界面,无需切换程序即可完成网络API请求,让你的code更加沉浸式. 安装 File->Setti ...
- 配置javaJDK环境
1.官网下载JDK包 2.解压包 3.打开vi /etc/profile文件添加一下内容 export JAVA_HOME=/usr/jdk1.8.0_121 #你的jdk所在的目录 export C ...
- 移动端web自适应适配布局解决方案
100%还原设计图,要注意: 看布局,分析结构. 感觉难点在于: 1.测量精度(ps测量数据): 2.文字的行高. 前段时间写个移动端适配的页面(刚接触这方面),查了一些资料,用以下方法能实现: 1. ...
- JavaScript面试总结(一)
(一).call,apply,bind 的用法与区别? 答案:摘自:https://www.cnblogs.com/Jade-Liu18831/p/9580410.html(总结的特别棒的一篇文章) ...
- JAVA程序员学PHP
工作之余,趁着五一假期学习下PHP,都说PHP是世界上最美的语言,而且现在应用的有这么广泛,在短期时间内在编程的市场上打得火热,好奇心趋势我去学习一下,下面便是我学习PHP记录下来的过程,和大家分享一 ...
- ccflow表机构与运行机制(二次开发必看)
驰骋工作流引擎,工作流程管理系统,表结构与运行机制. ------------------------------------------------------- 前言: 1, ccflow 有自动 ...
- ASP.NET Core 一步步搭建个人网站(1)_环境搭建
ASP.NET Core2.0发布有一阵子了,这是.NET 开源跨平台的一个重大里程碑, 也意味着比1.0版本要更加成熟.目前.net core具有开源.跨平台.灵活部署.模块化架构等等特性,吸引着一 ...
- java之日志管理
一. 为什么要使用日志 二. 常见日志框架介绍 三. Logback+SLF4J实战 四. 项目源码下载 五. 参考文章 一. 为什么要使用日志 1. 对IT安全至关重要 当您使用强大的日志管 ...