AOF持久化在硬盘上保存的是对Redis进行的逻辑操作,类似InnoDB中的bin log。说白了就是你对一个Redis输入了哪些语句,AOF文件都会原封不动的保存起来,等到需要回复Redis的时候再把这些语句执行一遍。

11.1 AOF持久化的实现

  AOF简单的理解是把执行的语句记录在硬盘的文件上。

  操作系统对文件的写入进行了一些优化,即把一条记录写在硬盘上需要分为两步:1、文件写入缓冲区 2、缓冲区内容同步。为了提高文件的读写速度,当用户调用write函数后,操作系统会把写入的数据暂存在内存缓冲区里。当 内存缓冲区满或者超过缓冲时限后,才会把缓冲区内容同步到硬盘上。这样做的优点是提高了读写效率,每次写入只需写到缓存里而不需要写到硬盘,缺点是具有一定的不安全性,如果缓冲区的内容没有及时同步到硬盘上此时计算机宕机那么就会失去这部分数据。为此操作系统提供了fsnsc fdatasync两个同步函数,强制同步缓冲区的数据到硬盘上。

  AOF同步也是一种把记录写到硬盘上的行为,在上述两个步骤之外,Redis额外加一步命令,Redis先把记录追加到自己维护的一个aof_buf中。所以AOF持久化分为三步:1、命令追加 2、文件写入 3.文件同步

11.1.1 命令追加

  服务器再执行完一条指令后会以规定的格式追加到aof_buf的末尾。如执行完SET KEY V1后,aof_buf末尾会多以下内容。

  

11.1.2 AOF文件的写入与同步

  完成aof_buf写入后Redis会执行flushAppendOnlyFile,该方法根据配置文件的不同而采用不同的策略把aof_buf里的内容刷到内存缓冲区里,具体的根据appendfsync的取值来决定不同的策略。

  • always,每次执行flushAppenfOnlyFIle的时候都会把aof——buf的内容刷到文件缓冲区,并且会同步缓冲区到硬盘
  • everysec,把aof_buf刷到文件缓冲区,之后两次文件缓冲区同步间隔超过1秒才会同步缓冲区
  • no,只刷到文件缓冲区,不管同步的事情

  三种模式下安全性和效率性的比较

  • always每次都要同步缓冲区,速度较慢,但不会出现内容缺失
  • everysec,速度比always要快,但是有可能会损失一定的数据,不过损失最多是1秒钟
  • no,执行速度最快,把文件缓冲区同步的调度交给了操作系统,安全性较差。并且当缓冲区积累到一定程度而不得不把内容写会文件系统后,会消耗大量的时间来完成同步的过程。所以均摊来看no 和 everysec效率类似。

11.2 AOF文件的载入与数据还原

  如何从AOF文件中恢复之前保存的数据?AOF是一个逻辑的日志,只需要把AOF从头到尾执行一遍即可。Redis服务器端设计的是执行客户端发出的指令,所以在回复AOF文件的时候创建了一个伪客户端从AOF文件中读取内容发送Redis服务器端实行,当AOF文件全部执行完毕后数据库也就恢复了。

11.3 AOF重写

  比如在操作Redis过程中把一个key的值从A改成了B然后又改回了A,此时AOF文件中有两条记录:A->B->A。所以在回复的时候回执行两次回复语句,但事实上是中间的两次变化是冗余的。随着Redis的执行,AOF不仅会变得冗余体积也会膨胀的更大。

  为了解决冗余带来的体积膨胀,Redis提供了AOF文件重写功能,通过AOF文件重写得到的新AOF文件,其恢复的结果和旧的AOF文件相同,但是体积更小因为他不会包含冗余指令。

11.3.1 AOF文件重写的实现

  AOF文件重写的逻辑非常简单,并不是分析旧的文件去除冗余指令,而是直接获取当前Redis的快照,然后用一条指令实现当前快照的结果并保存到AOF文件中。

  Redis作为一个成熟的产品,在这种我想不到的细节处也做了优化。在AOF持久化时写入磁盘的时候会先写到缓冲区,然后再同步到硬盘里。如果把10条很短的写硬盘的命令浓缩成一个很长的写语句,那么此时有可能发生缓冲区溢出,所以当压缩后的一条语句很长的时候Redis会把他拆分成相对短的指令。

11.3.2 AOF后台重写

  仔细回顾一下AOF重写其实很简单:得到当前Redis的一个快照,然后把逻辑指令写到硬盘上。现在有两个问题:

1、Redis使用单个线程来处理指令,如果指令去执行文件写操作--一个势必会带来大量阻塞时间的操作,此时会无法响应客户端的请求。所以必须要使用子进程来实现AOF重写,为什么是子进程而非子线程呢?是为了在不加锁的情况下仍然能够保证安全,因为子进程做的事情很单纯读取快照、生成AOF文件。不会和工作的进程产生任何冲突

2、数据不一致。子进程读取的是快照,而且当重写期间父进程仍然在工作所以快照和Redis数据库会存在数据不一致的情况。为了解决这个问题Redis设置了重写缓冲区。

第11章 AOF持久化的更多相关文章

  1. 【笔记】《Redis设计与实现》chapter11 AOF持久化

    11.1 AOF持久化的实现 命令追加 当AOF持久化处于开启状态时,服务器执行完一个写命令之后,会以协议格式将被执行的写明了追加到服务器状态的aof_buf缓冲区 struct redisServe ...

  2. 第二部分之AOF持久化(第十一章)

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

  3. redis基础:redis下载安装与配置,redis数据类型使用,redis常用指令,jedis使用,RDB和AOF持久化

    知识点梳理 课堂讲义 课程计划 1. REDIS 入 门 (了解) (操作)   2. 数据类型 (重点) (操作) (理解) 3. 常用指令   (操作)   4. Jedis (重点) (操作) ...

  4. Redis详解(七)------ AOF 持久化

    上一篇文章我们介绍了Redis的RDB持久化,RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失).对于数据完整性要求很严 ...

  5. 使用AOF持久化文件实现还原Redis数据库并得到RDB持久化文件

    目录 1 编写本文的初衷 2 具体实施 2.1 Redis持久化概念简介 2.2 获取指定Redis的AOF持久化文件 2.3 把Redis的持久化AOF文件转换为RDB文件 1 编写本文的初衷 因为 ...

  6. MySQL性能调优与架构设计——第11章 常用存储引擎优化

    第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ...

  7. redis 笔记03 RDB 持久化、AOF持久化、事件、客户端

    RDB 持久化 1. RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据. 2. SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器. 3. BGSAVE由子进程执行保 ...

  8. Redis实现之AOF持久化

    AOF持久化 除了RDB持久化功能之外,Redis还提供了AOF(Append Only File)持久化功能,与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Red ...

  9. redis源码分析(四)--aof持久化

    Redis aof持久化 Redis支持两种持久化方式:rdb与aof,上一篇文章中已经大致介绍了rdb的持久化实现,这篇文章主要介绍aof实现. 与rdb方式相比,aof会使用更多的存储空间,因为它 ...

随机推荐

  1. .NET 发送电子邮件

    static void Main(string[] args) { ///先引入 using System.Net.Mail; ///发送邮件 using (MailMessage mailMessa ...

  2. 如何将字符串格式的对象转换成真正的js对象?

    1.如何将字符串格式的对象转换成真正的js对象? <script>//eval 的作用eval('var a = 100');console.log(a);</script> ...

  3. js实现本地图片文件拖拽效果

    如何拖拽图片到指定位置,具体方法如下 在从本地上传图片的时候,如果使用拖拽效果,想想应该是更加的高大上,下面直接上js代码 完整代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  4. Grafan+Prometheus 监控 MySQL

    架构图 环境 IP 环境 需装软件 192.168.0.237 mysql-5.7.20 node_exporter-0.15.2.linux-amd64.tar.gz mysqld_exporter ...

  5. 《JavaScript高级程序设计》笔记:引用类型(五)

    Object类型 创建object实例方法有两种.第一种方法使用new操作符后跟object构造函数.如下: var person=new Object(); person.name="Ni ...

  6. 关于TensorFlow你需要了解的9件事

    关于TensorFlow你需要了解的9件事 https://mp.weixin.qq.com/s/cEQAdLnueMEj0OQZtYvcuw 摘要:本文对近期在旧金山举办的谷歌 Cloud Next ...

  7. phpcms调用指定文章内容模型的ID

    一.使用GET调用Phpcms V9指定id页面数据方法 {pc:get sql="SELECT * FROM cmsyou_news WHERE id='55'" cache=& ...

  8. Testlink1.9.17使用方法(第八章 测试执行/报告BUG)

    第八章 测试执行/报告BUG QQ群交流:585499566 把他们放到一起,是因为报告bug是在执行的过程中同步进行的——即执行用例的过程中一旦发现bug我们需要立即把其报告到我们的bug管理系统r ...

  9. Appium+java 模拟键盘输入

    功能键   KEYCODE_CALL 拨号键 5 KEYCODE_ENDCALL 挂机键 6 KEYCODE_HOME 按键Home 3 KEYCODE_MENU 菜单键 82 KEYCODE_BAC ...

  10. MySQL 安装及卸载详细教程

    本文采用最新版MySQL8版本作为安装教程演示,本人亲试过程,准确无误.可供读者参考. 下载 官网下载 --> 社区免费服务版下载. 下载Windows安装程序MySQL Installer M ...