什么是AOF持久化?

在前边也说了RDB持久化,AOF(Append only File)也是保存数据库状态的一种方式。它和RDB持久化的区别就是RDB是存的数据,而AOF存的是命令。

AOF的实现

AOF的实现可以分为命令追加,文件写入,文件同步三个步骤。

  1. 命令追加

在AOF功能打开时,服务器每执行一个指令后,它会以协议格式将被执行的命令追加到服务器状态的aof_buf缓冲区的末尾。这也就是命令的追加。

  1. 文件写入与同步

前文也提到过,Redis服务器的进程就是一个事件循环,在循环的过程中负责接受和回复客户端的请求。在执行客户端命令时,有可能会处理一些文件,可以也会操作一些写命令,使这些命令追加到aof_buf后,因此在服务器每处理完成一个事件前,会调用flushAppendOnly()函数,函数里也包含由是否将buf缓冲区的文件写到AOF文件中。而此函数由服务器配置选项的appendfsync来决定。默认为everysec

| appendfsync | flushAppendOnlyFile |

| allways | 将缓冲区的所有写入并同步到AOF文件 |

| everysec | 将缓冲去所有写入AOF文件,如果距离上次同步超过1s,那就再次进行同步(这个同步操作是一个线程专门负责执行的)|

| no | 将缓冲区文件写入到AOF,但是不进行同步(何时同步由操作系统决定)|

对比上边机中方式各由什么优缺点,第一种和第二中中有同步函数,可以强制让操作系统立刻将缓冲区的数据写入硬盘,保证了数据的安全性。第三种方法,提高了文件写入的效率,调用write函数将数据写入到文件时,会暂时将数据保存在缓冲区,当缓冲区被填满或者超时时才会将数据写入硬盘,这样的问题是不安全,并且极其容易造成数据丢失。

AOF文件的载入和数据还原

前文说到过,AOF存的是命令也就是也就是说它下一次恢复的时候就再把这些命令重新执行一边就又回到上一次同步时的状态了。

AOF文件读入并还原:

  1. 刚开始会创建一个不带网络的伪客户端(带不带网络数据恢复的结果是一样的,并且Redis命令只能在客户端执行,所以创建一个伪客户端)。

  2. 服务端从AOF文件读一条命令。

  3. 伪客户端执行传过来的写命令。并不断重复上一步和这一步,直至命令全被处理完。

AOF重写

什么是文件重写?

随着服务器的不断运行,AOF文件也是越来越大,不加以控制的话则有可能会对Redis服务器和计算机造成影响,并且文件越大,还原时需要的时间也就越多,那有没有什么方法来解决这些问题呢?因此就出现了文件重写(rewrite),使用该功能Redis服务器就会新建一个AOF文件,对原来的AOF文件进行精简(怎么个精简法看后文解释)并且让恢复后的各个数据库状态和普通AOF文件写入后载入相同。

解密怎么进行文件重写

文件重写并不是对原来的文件重新进行读取或者删改操作,是通过读取服务器当前的数据库状态来实现的。

比如举一个例子,我们创建一个集合对象,并每次向集合添加一个元素,添加了很多元素后,AOF文件就会越来越大,我们需要恢复这些数据的时候,如果按原始的AOF文件来的话还是要一条一条的写并且冗余程度太高。因为,这些条指令可以用一条指令来代替,就是一次性将这些数据添加到集合里,所以,文件重写就是利用这样的方式。

文件重写的步骤

遍历所有非空数据库,并写入每个非空数据库的编号,遍历数据库中所有的键(忽略过期键)根据各个类型进行重写(尽量减少命令的冗余),如果键带有过期时间,那过期时间也要被写入。因此这样重写AOF文件,就不会造成硬盘空间的浪费。

但是这种情况不是绝对的,在重写程序处理列表,哈希表,集合,有序集合这四种可能会又很多元素的键时,会先对此键所包含的元素数量进行检测,如果超过了REDIS_AOF_ITMES_PER_CMD的值就会用SADD命令记录这个集合。以当前版本64为例,如果一个集合有200条数据,它就会先SADD64个数据,然后再使用SADD64个数据,然后再使用SADD64个数据,然后再SADD剩余的数据。(其余机中类型也如此)

AOF的后台重写

虽然AOF重写可以很好的完成一个AOF文件,但是在很多时候数据量很大如果在主进程进行重写的话,会阻塞进程而使其他工作在此期间不能进行。因此,这样做肯定不是一个好的注意。所有,还是采取了和前边生成RDB文件后台执行相同的思想,派生出一个子进程专门来完成这件事情

后台重写的好处

  • 在重写期间服务器(父进程)可以处理客户端来的命令。
  • 在子进程中带有服务器数据的副本,使用子进程(不是子线程)可以在避免用锁的情况下完成任务,保证了数据的安全。

使用子进程而不是线程带来的问题?

使用子进程而不是子线程会导致文件状态可能不一致,因为在AOF重写期间,父进程要处理一些命令,新的命令可能会使数据库状态发生改变,然而子进程并不知道这些东西,这个问题该如何解决呢?

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

因此在子进程执行AOF重写期间,服务器进程需要执行以下三个工作:

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

这样的好处是什么?

  • 首先AOF缓冲区的内容定期被写入和同步到AOF文件中,对现有的AOF文件处理工作会正常进行。(注意AOF是始终存在的只不过重写的AOF更加精简)
  • 从创建子进程开始,所有的写命令都会记录在AOF重写缓冲区里。

和前边RDB一样,子进程完成后会发一个信号给父进程,然后父进程接受到信号会调用一个信号处理的函数并执行以下的工作:

  1. 将AOF重写缓冲区的所有内容写到新的AOF文件中,这时的AOF文件保存的数据库状态和服务器当前状态是完全一致的。
  2. 对新的AOF文件进行改名,并原子性的替换掉现有的AOF文件。

这样就彻底解决主进程阻塞的问题了吗?当然不是,为了保持同步,父进程在调用信号处理函数的时候会阻塞。虽然主进程会有短暂的阻塞,但是这已经是既能减少阻塞时间,又能保证AOF同步的最好方法了!

Redis设计与实现AOF持久化相关推荐

  1. Redis设计与实现RDB持久化

    什么是RDB持久化? RDB持久化就是将Redis在内存中产生的数据保存在磁盘里,防止数据的丢失.(Redis是一个内存数据库,一旦进程退出,数据库状态也就消失不见了) RDB文件是一个二进制文件,保 ...

  2. redis(11)--AOF持久化

    目录 持久化实现 命令追加 写入与同步 载入与数据还原 还原步骤 AOF重写 AOF重写实现 AOF 后台重写 AOF 后台重写的触发条件 Redis 分别提供了 RDB 和 AOF 两种持久化机制: ...

  3. Redis的RDB与AOF持久化机制

    所谓持久化,就是把缓存内容写进磁盘永久存储(你不删,磁盘不坏可不就是永久嘛) RDB RDB 是 Redis 默认的持久化方案. RDB快照(Redis DataBase):当满足一定条件的时候,会把 ...

  4. 一文通透讲解Redis高级特性,多线程/持久化/淘汰机制等统统搞定

    Redis 是一个开源的,基于内存的可持久化的非关系型数据库存储系统.在实际项目中可以用 Redis 做缓存或消息服务器,Redis 也是目前互联网中使用比较广泛的非关系型数据库,下面就来深入分析Re ...

  5. 翼支付门户架构之redis之RDB和AOF

    Redis 持久化: 提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AO ...

  6. 《Redis设计与实现》之第十一章:AOF持久化

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

  7. 《Redis设计与实现》第十一章 AOF持久化

    第十一章 AOF持久化 11.1 AOF持久化的实现 AOF持久化功能实现分为命令追加.文件写入.文件同步三个步骤. 11.1.1 命令追加 当AOF持久化功能出于打开状态时,服务器执行完一个写命令之 ...

  8. 《Redis设计与实现》笔记|SDS动态字符串|链表字典跳跃表整数集合压缩列表结构|redis中的对象|数据库原理|RDB持久化|AOF持久化|事件与多路利用模型|发布订阅原理|事务原理|慢查询日志

    <Redis设计与实现>笔记 前记: 参考配套网站:http://redisbook.com 带注释的源码地址:https://github.com/huangz1990/redis-3. ...

  9. 《Reids 设计与实现》第八章 AOF持久化

    <Reids 设计与实现>第八章 AOF持久化 文章目录 <Reids 设计与实现>第八章 AOF持久化 一.简介 二.AOF 持久化的实现 1.命令追加 2.AOF 文件的写 ...

最新文章

  1. springCloud Zuul网关
  2. ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
  3. C#的TreeView标记
  4. 你可能不知道的Python面试秘籍 干货满满(附带参考答案)上篇
  5. 中国大学MOOC 人工智能导论第七章测试
  6. 根据要求调参用matplotlib做一个一模一样的直方图(以及如何把成图变得更好看)
  7. 前端-页面性能调试:Hiper
  8. Could not connect to Redis at 127.0.0.1:13141: Cannot assign requested address
  9. windows播放声音
  10. SpringBoot(十六)_springboot整合JasperReport6.6.0
  11. matlab模式识别大作业_史上最萌最认真的机器学习/深度学习/模式识别入门指导手册(二)...
  12. 班级管理系统(SSM+LayUI)
  13. 凡刻(Fenke)FK169机械手表测评
  14. 字符串的getBytes方法
  15. 第一行代码android网课,使用Mongodb实现打卡签到系统的实例代码
  16. Windows上的Oracle检查列表。 (文档ID 443813.1)
  17. photoshop中的快速选择工具
  18. HTML5网页好看的一些特效
  19. 申请计算机课代表,课代表申请书的格式是怎样的啊???
  20. Delphi FMX正确设计和加载图片满足分布式跨平台App的性能需求-分布式跨平台App中美工图片的处理、上传下载、并发及客户端显示技术架构

热门文章

  1. 双向队列(STL做法)
  2. Jquery学习笔记:获取jquery对象的基本方法
  3. 《计算机组成与体系结构:性能设计》读后小记 4、cache存储器
  4. IE6 PNG 透明的方法
  5. 名为“ds”的+DataTable+已属于此+DataSet
  6. mysql手工注入——盲注
  7. [python学习] 专题九.Mysql数据库编程基础知识
  8. 96. Unique Binary Search Trees 不同的二叉搜索树
  9. 编译原理习题(含答案)
  10. ubuntu下安装并配置VIM编辑器