Redis-AOF重写,AOF后台重写实现原理

why

AOF(append only file)对Redis进行持久化是通过保存被执行的写命令来记录数据库状态的,随着服务器运行,AOF文件内容越来越多,载入AOF文件的时间会越来越长,影响Redis服务。
所以有必要对’冗余‘的AOF文件进行优化,即AOF文件重写。
那为什么要进行AOF后台重写?因为Redis单线程特性,AOF重写操作会引入大量写操作,引起stop the world,所以fork出子进程执行AOF后台重写,这样父进程可以继续处理命令请求。

AOF重写原理

怎么重写?是对旧的AOF文件进行读取、分析后进行优化吗?Redis没有采用,Redis是通过读取服务器当前数据库状态实现该功能的。
举个例子:
对一个animals键执行以下命令:

SADD animals "Cat"
SADD animals "Dog" "Tiger"
SREM animals "Tiger"

为了保存上述状态,AOF需要进行3次命令保存。
AOF重写后只需要读取animals键的所有值,再用SADD animals “Cat” "Dog"一条命令即可。
从3条减少为1条,减少了文件体积。

AOF后台重写原理(BGREWRITEAOF命令)

使用子进程(而不是开启一个线程)进行AOF重写虽然可以避免使用锁的情况下,保证数据安全性,但是会带来子进程和父进程一致性问题。
例如在开始重写之后父进程又接收了新的键值对此时子进程是无法知晓的,当子进程重写完成后的数据库和父进程的数据库状态是不一致的。

见下表:

时间服务器进程(父进程)子进程
T1执行命令 SET K1 V1
T2执行命令 SET K1 V1
T3执行命令 SET K1 V1
T4创建子进程,执行AOF文件重写开始AOF重写
T5执行命令 SET K2 V2执行重写
T6执行命令 SET K3 V3执行重写
T7执行命令 SET K4 V4完成AOF重写

在T7时刻服务器进程有了4个键,而子进程只有1个键,即所谓的漏追加。

为了解决这种不一致性,redis设置了一个AOF重写缓冲区。

在这里插入图片描述

在子进程执行AOF重写期间。服务器进程需要执行以下3个动作:

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

执行完上述3个操作后可以保证:

  • AOF缓冲区内容会定期被写入和同步到AOF文件,对现有AOF文件处理正常进行
  • 子进程开始,服务器执行的所有写命令都会进入AOF重写缓冲区

子进程完成AOF重写后,它向父进程发送一个信号,父进程收到信号后会调用一个信号处理函数,该函数把AOF重写缓冲区的命令追加到新AOF文件中然后替换掉现有AOF文件。父进程处理完毕后可以继续接受客户端命令调用,可以看出在AOF后台重写过程中只有这个信号处理函数会阻塞服务器进程。
下表是完整的AOF后台重写过程:

时间服务器进程(父进程)子进程
T1执行命令 SET K1 V1
T2执行命令 SET K1 V1
T3执行命令 SET K1 V1
T4创建子进程,执行AOF文件重写开始AOF重写
T5执行命令 SET K2 V2执行重写
T6执行命令 SET K3 V3执行重写
T7执行命令 SET K4 V4完成AOF重写,向父进程发送信号
T8接收到信号,将T5 T6 T7 服务器的写命令追加到新的AOF文件末尾
T9用新的AOF替换旧的AOF

T8 T9执行的任务会阻塞服务器处理命令。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值