当前位置: 首页 > news >正文

Redis的AOF持久化策略(AOF的工作流程、AOF的重写流程,操作演示、注意事项等)

文章目录

  • 缓冲AOF 策略(append only file)
  • AOF 的工作流程
  • AOF 缓冲区策略
  • AOF 的重写机制
  • 重写完的AOF文件为什么可以变小?
  • AOF 重写流程

缓冲AOF 策略(append only file)

AOF 的核心思路是 “实时备份“,只要我添加了新的数据或者更新了新的数据,就立刻将数据备份到硬盘中。

在 Redis 的配置文件中,默认是将 AOF 这种方式关闭的,所以我们想要使用 AOF 时,就需要修改一下配置文件,如下图:

在这里插入图片描述

然后重启服务器,就会自动生成一个 aof 文件,aof 文件的位置和 rdb 文件的是一样的,都是在 /var/lib/redis 目录下

在这里插入图片描述

下面我们来设置几个键值对进行测试:

  1. 设置键值对

在这里插入图片描述

  1. 使用 kill -9 杀死redis进程

在这里插入图片描述

当这里杀死完 redis 进程后,由于 unbent 系统的保护措施,会自动再启动一个 redis 服务器

  1. 查看redis内存中的键值对是否进行了备份

从下图可以看到,aof 文件中,已经实时的自动帮我们进行了备份了,并且,也可以看到,这个 aof 文件是一个文本文件。

在这里插入图片描述
在这里插入图片描述

如果我们开启了 AOF,在 aof 文件中进行了备份,又通过 bgsave 命令在 rdb 文件中进行备份,那么在重启 redis 服务器后,它是会加载两个文件中的数据吗???

答案:并不是的,当我们开启了 AOF 后,rdb 文件就不会再使用了,这个文件就相当于是透明的了,接下来的备份操作以及读取数据都是在 aof 文件中进行的。

AOF 的工作流程

Redis 之所以速度很快,最主要的原因是因为:它是操作内存的。

但是,在引入了 AOF 之后,又要写内存,又要写硬盘,那么样不久大大拖慢了速度吗???

实际上,并没有什么太大的影响的,因为,AOF 机制并非是直接让工作线程把数据写入硬盘,而是先写入到一个内存缓冲区中(AOF缓冲区),等到积累的一定量的数据之后,再把缓冲区的数据一次性写入到硬盘中,此时就大大降低了写硬盘的次数,在写硬盘的时候,写入数据的多少对于性能影响没有很大,但是写硬盘的次数则影响很大了!!!

通过上述的讲解,此时就又会出现一个问题,如果把数据写入到内存缓冲区里,本质上还是在内存里呀,如果万一掉电了或者进程挂了,此时数据不久丢失了吗???

答案:是的,这种情况下,数据确实就会丢失。而AOF 机制就给了我们一些选项,也就是缓冲区的刷新策略,让我们根据实际情况对 ”效率“ 和 ”数据的可靠性“ 作一个取舍。

当刷新频率越高时,性能影响就越大,同时数据的可靠性就越高。

刷新频率越低时,性能影响就越小,同时数据可靠性就降低了,数据就容易丢丢失。

就像mysql的隔离级别一样,想要提高隔离性,并发程度就降低了,想要提高并发程度,隔离性就降低了。

此时,就让我想起了苏轼的一句话,人有悲欢离合,月有阴晴圆缺,此事古难全。想要鱼和熊掌兼得,这是不容易的,

AOF 缓冲区策略

AOF 缓冲区的策略是在配置文件中由 appendsync 参数的值控制的,策略值都有以下几个:

aways频率是最高的,数据的可靠性最高,性能最低
everysec频率降低,数据的可靠性减低,性能得到提高
no频率最低,数据的可靠性最低,性能最高

在配置文件中,默认的就是 everysec,如下图:

在这里插入图片描述

AOF 的重写机制

AOF 它的设定是将用户的每次操作都写入到 AOF 中,但是随着 redis 的持续运行,AOF 的文件就会越来越大,体积大了之后,就会影响到 redis 的下次启动时间,因为 redis 启动的时候,就要恢复数据,如果数据太多,就会影响启动时间,这是其一,其二就是 aof 文件中有一些内容是冗余的!!!

举个例子,如下图:

在这里插入图片描述

以上,这三次操作过程就可以转化成一次操作,所以这三次操作过程就是冗余的。

所以,针对 aof 文件过大的问题,就利用了重写机制给 aof 文件进行重写,就可以达到瘦身效果。

重写完的AOF文件为什么可以变小?

首先呢,在 redis 的 aof 文件中,记录的是整个操作过程,例如 lpush key 111 ,但是,redis 在启动的时候,并不关注这些过程,只是关注这些结果,也就是内存中都有哪些数据。

所以,就对 aof 文件进行整理 ,这个整理是能够剔除其中的冗余操作,并且合并一些操作,达到给 aof 文件瘦身这样的效果。就相当于中间的过程能去掉就去掉,只保留结果即可。

而且,在旧的 aof 文件中,也可能会存在像 del、hdel、srem这样的删除命令,但是经过这样的命令之后,数据都被删除了,而在aof文件中保留的这些删除操作也没啥用,所以也要进行清除掉,所以,重写完的 aof 文件就会变小。

AOF 重写流程

AOF 的重写也是分为以下两种:

① 手动触发:调用 bgrewriteaof 命令

② 自动触发:在配置文件中,根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。

  • auto-aof-rewrite-min-size :表示当文件达到多大时,就触发重写操作,默认位 64MB
  • auto-aof-rewrite-percentage:表示当前 AOF 文件的大小相比较上次重写时的比例,比如,指定了这个比例是 50%,如果上次重写是的文件大小是 0.5g,当前文件大小是 1g,此时就会触发自动重写。

重写流程如下:

① 父进程通过fork创建出子进程,此时,父进程仍然负责接收客户端请求,子进程负责针对 aof 文件进行重写。

那么,这个重写是具体是如何重写的呢???

其实,重写的时候,并不关心 aof 文件中原来都有啥,只是关心内存中最终的数据状态,所以,在进行重写时,并不需要再去遍历旧的 aof 文件,把最终结果整理出来,因为,我们只需要获取到最终的数据即可,而最终的数据现在也就是在内存中保存着的呀,所以,子进程只需要把内存中当前的数据,获取出来,以 AOF 的格式写入到新的 aof 文件中即可。

此处的子进程写数据的过程,非常类似于 RDB 生成一个快照文件,只不过,RDB 这里是按照二进制的方式生成的,AOF 重写,则是按照 AOF 这里要求的文本格式来生成的。

② 子进程在重写的过程中呢,父进程也还仍然在不停的接收客户端发来的请求,此时,父进程还是会把这些请求产生的 AOF 数据先写入到“缓冲区”中,再刷新到旧的 AOF 文件中。

而且要注意,在创建子进程的一瞬间,它就相当于继承了当前父进程的内存状态,也就是当前父进程的内存中有啥,子进程的内存中就有啥(这里看起来父进程和子进程好像是同一块内存空间,其实是不同的内存空间,子进程是对父进程的内存空间进行了拷贝,只不过是按照写实拷贝的方式进行的)而子进程中只是包含了 fork 之前的内存数据,而 fork 之后,新来的请求对内存造成的修改,子进程是感知不到的。

③ 但是此时,父进程这里有准备了一个 aof_rewrite_buf,这里就会专门放 fork 之后收到的数据,所以,在 fork 之后,父进程不仅要向 aof_buf 缓冲区中写入数据,还要向 aof_rewrite_buf 缓冲区中写数据。aof_buf 缓冲区主要还是为了往旧的 aof 文件中写数据,而 aof_rewrite_buf 主要是为了后续往新的 aof 文件中写数据,等到子进程这边把数据重写完之后,就会通过“信号”通知一下父进程,父进程再把 aof_rewrite_buf 缓冲区中的数据也写入到新的 aof 文件中。这也就意味着,新的 aof 文件中的数据主要来自两方面,一个是 fork 之前的数据,一个是 fork之后的数据,等到父进程这里也写完之后,就可以用新的 aof 文件代替旧的 aof 文件了。

如果在执行 bgrewriteaof 的时候,当前的 redis 已经正在进行 aof 重写了,会怎么样呢???

也就是上一个重写操作还没完成,此时,就又来了个 bgrewriteaof 命令,此时,父进程会进行一个判定,如果此时正在重写,就不会再次执行 bgrewriteaof 命令了。

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

此时,aof 重写操作会等待,等到 rdb 快照生成完毕之后,再进行重写。

因为最后都是要写入到新的 aof 文件中,并且,新的 aof 文件最后也会替代旧的 aof 文件,那么,在fork之后,写入数据时,为啥还要再将数据写入到旧的 aof 文件中呢。不写旧的aof文件,直接将数据都交给子进程写新的aof文件不行吗???

为最后都是要写入到新的 aof 文件中,并且,新的 aof 文件最后也会替代旧的 aof 文件,那么,在fork之后,写入数据时,为啥还要再将数据写入到旧的 aof 文件中呢。不写旧的aof文件,直接将数据都交给子进程写新的aof文件不行吗???

答案是:不行,如果出现一种极端的情况,比如,子进程在重写的过程中,重写了一半了,服务器挂了,显然这样的重写就断了,子进程内存中的数据就丢失了,新的 aof 文件内容还不完整,此时,并且缓冲区中的数据也会烟消云散了,那么如果没有写旧的aof文件,那就凉凉喽~~

相关文章:

Redis的AOF持久化策略(AOF的工作流程、AOF的重写流程,操作演示、注意事项等)

文章目录 缓冲AOF 策略(append only file)AOF 的工作流程AOF 缓冲区策略AOF 的重写机制重写完的AOF文件为什么可以变小?AOF 重写流程 缓冲AOF 策略(append only file) AOF 的核心思路是 “实时备份“,只要我添加了新的数据或者更新了新的数据&#xff0…...

共享模型之无锁

一、问题提出 1.1 需求描述 有如下的需求,需要保证 account.withdraw() 取款方法的线程安全,代码如下: interface Account {// 获取余额Integer getBalance();// 取款void withdraw(Integer amount);/*** 方法内会启动 1000 个线程&#xf…...

下载安装VSCode并添加插件作为仓颉编程入门编辑器

VSCode下载地址:下载 Visual Studio Code - Mac、Linux、Windows 插件下载:GitCode - 全球开发者的开源社区,开源代码托管平台 仓颉社区中下载解压 cangjie.vsix 插件 打开VSCode 按 Ctrl Shift X 弹出下图 按照上图步骤依次点击选中我们下…...

解决:Linux上SVN 1.12版本以上无法直接存储明文密码

问题:今天在Linux机器上安装了SVN,作为客户端使用,首次执行SVN相关操作,输入账号密码信息后,后面再执行SVN相关操作(比如"svn update")还是每次都需要输入密码。 回想以前在首次输入…...

Mongodb多键索引中索引边界的混合

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第93篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…...

如何利用windows本机调用Linux服务器,以及如何调用jupyter界面远程操控

其实这篇文章没必要存在,教程太多了 参考博客(1 2 3),如侵删 奈何网上的大神总是会漏掉一些凡人遇到的小问题 (1) 建议下载PuTTy for windows,从而建立与远程服务器的SSH连接 需要确认目标服…...

如何定位Milvus性能瓶颈并优化

假设您拥有一台强大的计算机系统或一个应用,用于快速执行各种任务。但是,系统中有一个组件的速度跟不上其他部分,这个性能不佳的组件拉低了系统的整体性能,成为了整个系统的瓶颈。在软件领域中,瓶颈是指整个路径中吞吐…...

阿里云服务器 篇三:提交搜索引擎收录

文章目录 系列文章推荐:为网站注册域名判断网站是否已被搜索引擎收录主动提交搜索引擎收录未查询到收录结果时,根据提示进行提交网站提交网站时一般需要登录账号主动提交网站可缩短爬虫发现网站链接时间,但不保证一定能够收录所提交的网站百度提交地址360搜索提交地址搜狗提…...

powe bi界面认识及矩阵表基本操作 - 1

powe bi界面认识及矩阵表操作 1. 界面认识1.1 选择数据源1.2 选择相关表及点击加载1.3 表字段显示位置1.4 表属性按钮位置1.5 界面布局按钮认识 2. 矩阵表基本操作2.1 选择矩阵表2.2 创建矩阵表2.3 设置字体大小2.4 行填充:修改高度2.5 列宽:设置列的宽度…...

SpringBoot 项目 pom.xml 中 设置 Docker Maven 插件

在Spring Boot项目中,使用Docker Maven插件(通常是docker-maven-plugin或者fabric8io/docker-maven-plugin)来自动化构建Docker镜像并将其推送到远程仓库。 这里分别介绍这两种插件的基本配置,并说明如何设置远程仓库推送。 1、…...

k8s二次开发-kubebuiler一键式生成deployment,svc,ingress

一 Kubebuilder环境搭建 注&#xff1a;必须在当前的K8S集群有 nginx这个ingressclass rootk8s:~# kubectl get ingressclass NAME CONTROLLER PARAMETERS AGE nginx k8s.io/ingress-nginx <none> 19h1.1 下载kubebuilder wget https://gi…...

Flutter 状态管理新境界:多Provider并行驱动UI

前言 在上一篇文章中&#xff0c;我们讨论了如何使用 Provider 在 Flutter 中进行状态管理。 本篇文章我们来讨论如何使用多个 Provider。 在 Flutter 中&#xff0c;使用 Provider 管理多个不同的状态时&#xff0c;你可以为每个状态创建一个单独的 ChangeNotifierProvider…...

标识符和关键字的区别是什么,常用的关键字有哪些?自增自减运算符,移位运算符continue、break、return的区别是什么?

标识符和关键字的区别是什么&#xff0c;常用的关键字有哪些&#xff1f; 标识符标识符就是当我们给变量&#xff0c;方法&#xff0c;类命名时候的名字&#xff0c;而被赋予特殊含义的标识符就是关键字。例如生活中&#xff0c;当我们需要开一家店时候&#xff0c;我们不能将…...

在VS Code上搭建Vue项目教程(Vue-cli 脚手架)

1.前期环境准备 搭建Vue项目使用的是Vue-cli 脚手架。前期环境需要准备Node.js环境&#xff0c;就像Java开发要依赖JDK环境一样。 1.1 Node.js环境配置 1&#xff09;具体安装步骤操作即可&#xff1a; npm 安装教程_如何安装npm-CSDN博客文章浏览阅读836次。本文主要在Win…...

AGI 之 【Hugging Face】 的【零样本和少样本学习】之三 [无标注数据] 的简单整理

AGI 之 【Hugging Face】 的【零样本和少样本学习】之三 [无标注数据] 的简单整理 目录 AGI 之 【Hugging Face】 的【零样本和少样本学习】之三 [无标注数据] 的简单整理 一、简单介绍 二、零样本学习 (Zero-shot Learning) 和少样本学习 (Few-shot Learning) 1、零样本学…...

Docker 和 k8s 之间是什么关系?

Docker 简介 Docker 功能&#xff1a; Docker 是一款可以将程序和环境打包并运行的工具软件。通过 Docker&#xff0c;可以将程序及其依赖环境打包&#xff0c;确保在不同操作系统上一致的运行效果。 环境一致性问题&#xff1a; 程序依赖于特定的环境&#xff0c;不同操作系统…...

敲详细的springframework-amqp-rabbit源码解析

看源码时将RabbitMQ的springframework-amqp-rabbit和spring-rabbit的一套区分开&#xff0c;springboot是基于RabbitMQ的Java客户端建立了简便易用的框架。 springboot的框架下相对更多地使用消费者Consumer和监听器Listener的概念&#xff0c;这两个概念不注意区分容易混淆。…...

Telegram Bot、小程序开发(三)Mini Apps小程序

文章目录 一、Telegram Mini Apps小程序二、小程序启动方式三、小程序开发小程序调试模式初始化小程序Keyboard Button Mini Apps 键盘按钮小程序【依赖具体用户信息场景,推荐】**Inline Button Mini Apps内联按钮小程序**initData 的自动传递使用内联菜单时候哪些参数会默认传…...

Django F()函数

F()函数的作用 F()函数在Django中是一个非常强大的工具&#xff0c;主要用于在查询表达式中引用模型的字段。它允许你在数据库层面执行各种操作&#xff0c;而无需将数据加载到Python内存中。这不仅提高了性能&#xff0c;还允许你利用数据库的优化功能。 字段引用 在查询表达…...

GraphRAG的实践

好久没有体验新技术了&#xff0c;今天来玩一下GraphRAG 顾名思义&#xff0c;一种检索增强的方法&#xff0c;利用图谱来实现RAG 1.配置环境 conda create -n GraphRAG python3.11 conda activate GraphRAG pip install graphrag 2.构建GraphRAG mkdir -p ./ragtest/i…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...