2023.1.17 关于 Redis 持久化 AOF 策略详解

news2024/9/30 19:37:14

目录

引言

AOF 策略

实例演示一

缓冲区

重写机制

手动触发

自动触发

AOF 重写流程 

实例演示二


引言

Redis 实现持久化的两大策略

  • RDB ——> Redis DataBase(定期备份)
  • AOF ——> Append Only File(实时备份)

注意:

  • Redis 服务器配置文件默认开启 RDB(定期备份)
  • 即 AOF(实时备份) 默认为关闭状态
  • 此处我们可以通过修改配置文件,来开启 AOF(实时备份)


可点击下方连接详细了解 RDB 策略

Redis 持久化 RDB 策略

AOF 策略

  • 该策略类似于 mysql 的 binlog,会将用户的每个操作均记录到文件中
  • 当 Redis 重新启动时,便会读取 aof 文件中的内容,将内存中的数据恢复回来

注意:

  • 当开启 AOF 时,rdb 文件便不会生效了
  • 即 Redis 启动时将不再读取 rdb 文件的内容用来恢复数据
  • 因为 aof 文件中包含的数据比 rdb 文件更全!

实例演示一

  • 根据实例演示,我们观察 aof 文件的生成,顺便观察 rdb 文件在 AOF 策略下的 Redis 是否生效

 1、当我们将 Redis 配置文件中的 RDB(定期备份)修改为 AOF(实时备份)后

  • 由上图可知,即便是没有 rdb 文件,Redis 服务器也可正常重启!

2、此时我们向 redis 中插入 2个键值对


3、查看 appendonly.aof 文件

  • 由上图可知,aof 文件为文本文件
  • 我们在 Redis 中进行的操作,均会被记录到 aof 文件中
  • 通过一些特殊符号作为分隔符,来对命令的细节做出区别

4、将现在正在运行的 Redis 服务器重启,看是否能恢复内存之前的状态

缓冲区

  • Redis 虽然是一个单线程的服务器,但是速度很快
  • 其中一个重要的原因为 Redis 仅操作内存

问题一:

  • 引入 AOF(实时备份)后,既要写内存,又要写硬盘,还能和之前一样快吗?

回答:

  • 没有什么影响,并不会影响到 Redis 处理请求的速度!

1、AOF 机制并非是直接让工作线程将数据写入硬盘,而是先写入内存中的缓冲区,积累一波后,再统一写入硬盘

  • 该方式大大降低了,写硬盘的次数
  • 写硬盘时,写入硬盘数据的多少,对于性能没有很大影响但是写入硬盘的次数则影响很大了

2、AOF 机制每次将新操作写入到原有文件的末尾,属于 顺序写入

  • 硬盘上读写数据,顺序读写的速度是比较快的(还是要比内存慢很多),而随机访问的速度则是比较慢的

问题二:

  • 数据写入到缓冲区里,其本质还是在内存中呀
  • 万一这时候,突然进程挂了 或 主机掉电了,是不是缓冲区中的数据就丢了呢?

回答:

  • 是的,缓冲区没来得及写入硬盘的数据是会丢的!
  • Redis 给出了一些选项,让程序员根据实际情况决定怎么取舍,即缓冲区的刷新策略
  • 刷新频率越高,性能影响就越大,数据可靠性就越高
  • 刷新频率越低,性能影响就越小,数据可靠性就越低

  • fsync 是一个系统调用,用于强制将文件系统中对应文件的所有修改刷新到磁盘上

注意:

  • 默认情况下为 everysec

重写机制

  • aof 文件持续增长,其体积将越来越大,从而影响 Redis 下次启动的启动时间
  • 因为 Reids 启动的时候要读取 aof 文件的内容

注意:

  •  aof 中的文件,有很多内容都是冗余的

  • 虽然 aof 文件的内容记录了中间的操作过程
  • 但实际 Redis 在重新启动时,仅关注最终的结果
  • 因此 Redis 存在 重写机制,能够针对 aof 文件进行 整理 操作
  • 所谓 整理 就是能够剔除其中的冗余操作,并且合并一些操作,以达到 aof 文件瘦身的效果

手动触发

  • 调用 bgrewriteaof 命令即可

自动触发

  • 根据配置项参数确定自动触发时机

  • auto-aof-rewrite-min-size: 表示触发重写时 aof 文件的最小文件大小
  • auto-aof-rewrite-percentage: 表示当前 aof 文件占用大小相比较上次重写时增加的比例

AOF 重写流程 


2)4)

  • 发生重写时,通过 fork 创建子进程
  • 在创建子进程的一瞬间,子进程便继承了当前父进程的内存状态
  • 子进程只需要将内存中当前的数据给获取出来,以 aof 的格式写入到一个新的 aof 文件中
  • 与此同时 子进程负责针对 aof 文件进行重写

注意点一:

  • 子进程里的内存数据是 父进程 fork 之前的状态
  • 而 fork 之后,对内存造成修改的新请求,子进程无法知道的!

注意点二:

  • 在此过程中并不关心 aof 文件中原来都有啥,仅关心内存中最终的数据状态
  • 内存中的数据状态,就已经相当于是把 aof 文件结果整理后的模样了

注意点三:

  • 此处 子进程 写数据的过程,非常类似于 RDB 生成一个镜像快照
  • 只不过 RDB 这里是按照二进制的方式来生成的
  • 而 AOF 重写,则是按照 AOF 这里要求的文本格式来生成的
  • 二者 都是为了把当前内存中的所有数据状态记录到文件中


1)2)3.1)

  • 在子进程写新 aof 文件的同时,父进程也仍然不停地接收客户端新请求
  • 并将这些请求产生的 aof 数据先写入到缓冲区再刷新到原有的 aof 文件中

2)3.2)

  • 正因为子进程里的内存数据是 父进程 fork 之前的状态
  • 而 fork 之后,对内存造成修改的新请求,子进程无法知道的!
  • 此时父进程这里便准备了一个 aof_rewrite_buf 缓冲区
  • 专门放 fork 之后收到的数据

5.1)5.2)

  • 子进程将 aof 数据写完后,便会通过 信号 通知父进程
  • 父进程再将 aof_rewrite_buf 缓冲区中的内容也写入到 新的 aof 文件中

注意:

  • 信号可以认为是 linux 的神经系统
  • 进程之间的相互作用(也可以视为是进程间通信的一种手段)
  • 但 Java 生态中并不鼓励适用多进程模型编程(网络通信的场景除外)
  • 信号能表达的信息有限,并非像 socket 这样的方式可以传输任意的数据
  • 这种简单的信号传递,使用信号也是 ok 的
  • 信号 接近于 JavaScript 里的 事件


5.3)

  • 最后便可以使用新 aof 文件替换旧 aof 文件了

问题一:

  • 如果在执行 bgrewriteaof 时,当前 Redis 正在进行 aof 重写,此时会怎样?

回答:

  • 此时将不会再次执行 aof 重写,而是直接返回

问题二:

  • 如果在执行 bgrewriteaof 时,发现当前 Redis 在生成 rdb 文件的快照,此时会怎样?

回答:

  • 此时 aof 重写操作便会等待,等待 rdb 快照生成完毕之后,再执行 aof 重写

问题三:

  • 在父进程 fork 完毕后,子进程开始重写新 aof 文件
  • 并且随着时间的推移,子进程将会很快写完新 aof 文件
  • 最后 新 aof 文件将代替旧 aof 文件
  • 那么 父进程此时还在继续写这个即将消亡的旧 aof 文件是否还有意义?

回答:

  • 考虑到极端情况
  • 假设在重写过程中,重写了一半,服务器挂了,子进程内存的数据就会丢失,此时新 aof 文件内容还不完整
  • 所以如果 父进程不坚持写旧 aof 文件,重启时便无法保证数据的完整性了

小总结:

  • RDB 对 fork 之后的新数据,便置之不理了
  • 而 AOF 则对 fork 之后的新数据,采取了 aof_rewrite_buf 缓冲区的方式来进行处理
  • RDB 本身的设计理念,就是用来 定期备份的
  • 只要是 定期备份,就难以和最新的数据保持一致
  • AOF 的理念则是实时备份
  • 当然 实时备份 并不一定就比 定期备份 更好,还是需要结合 实际场景 来看
  • 现在的系统,其资源一般都是比较充裕的,即 对于 AOF 所造成的开销也不会有太大负担
  • 所以 一般来说 AOF 的适用场景更多一些的!

实例演示二

  • 通过该实例演示 观察重写之后的 aof 文件

1、向 Redis 中进行下图操作


2、打开并查看  appendonly.aof 文件


3、在 Redis 中手动执行 bgrewriteaof 命令,手动触发 AOF 重启


4、再次观察 appendonly.aof 文件

  • 此时发现 数据居然以二进制的方式进行存储

注意:

  • AOF 本来是按照文本格式来写入文件的
  • 但是文本的方式写文件,后续加载的成本是比较高的
  • 所以 Redis 便引入了 混合持久化 的方式,即结合了 rdb 和 aof 的特点

具体解释:

  • 按照 AOF 的方式,将每个 请求 或 操作,均记录到文件中
  • 在触发 AOF 重写后,便将当前内存的状态按照 rdb 的二进制格式写入到新 aof 文件中
  • 后续再进行的操作,仍然按照 aof 文本的方式追加到文件后面


5、我们再往 Redis 中插入 1个键值对


6、再次打开并观察 appendonly.aof 文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux中的软件包管理器yum

目录 1.什么是软件包 2.关于 rzsz 3.查看软件包 4.如何安装软件 5.如何卸载软件 1.什么是软件包 ● 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. ● 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理…

EasyExcelFactory 导入导出功能的实战使用

EasyExcelFactory 导入导出功能的实战使用分享&#xff1a; 1、jar包引入 <!-- 阿里巴巴Excel处理--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.6</version></dependen…

华为AC+FIT AP组网配置

AC配置 vlan batch 100 to 101dhcp enableip pool apgateway-list 192.168.100.254 network 192.168.100.0 mask 255.255.255.0 interface Vlanif100ip address 192.168.100.254 255.255.255.0dhcp select globalinterface GigabitEthernet0/0/1port link-type trunkport trun…

本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面

文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask&#xff0c;以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架&#xff0c;采用Python编程语…

14027.ptp 控制流

文章目录 1 ptp 控制流1.1 控制流分层 1 ptp 控制流 1.1 控制流分层 大体分为4层&#xff1a;1 ptp4l层&#xff1a; 获取配置文件、创建时钟、poll监控文件描述符。2 clock时钟层&#xff1a;提供提供clock_poll、clock_create、clock_sync 等3 port 端口层&#xff1a;port…

数据结构与算法:图

文章目录 图1) 概念有向 vs 无向度权路径环图的连通性 2) 图的表示3) Java 表示4) DFS5) BFS6) 拓扑排序7) 最短路径DijkstraBellman-FordFloyd-Warshall 8) 最小生成树PrimKruskal 图 1) 概念 图是由顶点&#xff08;vertex&#xff09;和边&#xff08;edge&#xff09;组成…

如何搭建MariaDB并实现无公网ip环境远程连接本地数据库

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. 配置MariaDB数据库1.1 安装MariaDB数据库1.2 测试局域网内远程连接 2. 内网穿透2.1 创建隧道映射…

【C++】stack与queue的模拟实现

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 stack与queue的实现比较简…

Mysql - 定点型(DECIMAL)的使用详解及练习

目录 &#x1f436;1. 前言&#xff1a; &#x1f436;2. DECIMAL类型简介 &#x1f436;3. Decimal使用实战 &#x1f96a;#结论1&#xff1a;小数位不足会自动补0 &#x1f96a;#结论2&#xff1a;小数位超出会截断 并按四舍五入处理。 &#x1f96a;#结论3&#xff1…

代码随想录算法训练营第34天 |1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果

1005.K次取反后最大化的数组和 题目链接&#xff1a;1005.K次取反后最大化的数组和 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选…

【明道云】学习笔记1-了解APaaS

【背景】 APaaS (Application Platform As A Service) &#xff0c;即应用程序平台即服务&#xff0c;这是基于PaaS&#xff08;平台即服务&#xff09;的一种解决方案&#xff0c;支持应用程序在云端的开发、部署和运行&#xff0c;提供软件开发中的基础工具给用户&#xff0…

【JavaEE进阶】 Spring Boot⽇志

文章目录 &#x1f38b;关于日志&#x1f6a9;为什么要学习⽇志&#x1f6a9;⽇志的⽤途&#x1f6a9;日志的简单使用 &#x1f384;打印⽇志&#x1f6a9;程序中得到⽇志对象&#x1f6a9;使⽤⽇志对象打印⽇志 &#x1f38d;⽇志格式的说明&#x1f6a9;⽇志级别的作用&#…

Java - 深入理解加密解密和签名算法

文章目录 应用的接口安全性问题可能来源加密解密Why保护数据隐私防止未经授权的访问防止数据泄露 对称加密 VS 单向加密 VS 非对称加密一、对称加密二、单向加密&#xff08;哈希加密&#xff09;三、非对称加密 常用的对称加密算法1. AES&#xff08;高级加密标准&#xff09;…

【Java】学习一门开发语言,从TA的Hello World开始

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《Java》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握…

第15届蓝桥杯嵌入式省赛准备第二天总结笔记(使用STM32cubeMX创建hal库工程+按键输入)

一.查看电路图 按键是使用的PB0,PB1,PB2,PA0四个引脚&#xff0c;然后使用CubeMX配置引脚&#xff0c;4个脚都配置为输入模式和上拉。 程序生成之后把不用的删掉&#xff0c;需要的留下&#xff0c;这里我把函数名改了。 然后写按键扫描读取程序&#xff0c;这里参考的正点原子…

【Linux】—— 命名管道详解

命名管道是一种在操作系统中用于进程间通信的机制&#xff0c;它允许不同的进程之间通过管道进行数据交换。与匿名管道相比&#xff0c;命名管道具有更多的灵活性和功能。在本博客中&#xff0c;我们将深入探讨命名管道的概念、用途以及如何在编程中使用它们。 目录 &#xff…

【cucumber】cucumber-reporting生成测试报告

原始的cucumber report 比较粗糙 我们可以通过cucumber-reporting 插件对报告进去优化 在pom.xml里面添加cuccumber-reporting 插件 <!-- 根据 cucumber json文件 美化测试报告--><dependency><groupId>net.masterthought</groupId><artifactId>…

何为PyTorch?

PyTorch的名字来源于它的功能和设计哲学。"Py"代表Python&#xff0c;因为PyTorch是一个基于Python的深度学习库&#xff0c;它充分利用了Python语言的灵活性和易用性&#xff0c;为开发者提供了简洁而强大的接口。“Torch”则代表其前身—— Torch&#xff0c;这是一…

瓦片地图游戏开发的底层代码

原理&#xff1a; 二维数组存储每个瓦片序号 然后有一个缓冲区存储瓦片图片&#xff0c; 最后连续采样缓冲区&#xff0c;粘贴到屏幕上&#xff0c; 而缓冲区数据随着采样越界再重新更新 #include <graphics.h> #include <stdio.h>// 默认游戏地图 int map[20…

使用vue-pdf插件加载pdf

安装&#xff1a; // 安装这个版本&#xff0c;其它版本会有千奇百怪的错&#xff0c;这个版本和4.0.0都是可以的 cnpm install vue-pdf4.2.0// 安装pdfjs-dist cnpm install pdfjs-dist2.5.207 使用&#xff1a; // 我的css样式是pxToRem&#xff0c;友友们使用可能样式会有…