redis持久化方式—AOF

redis为什么需要持久化

redis是内存数据库,redis所有的数据都保存在内存中

如果此时pc关机或重启,那么内存中的用户数据岂不是丢失了?redis这么不安全吗?

作为数据库,保证数据的安全,持久是基本需求,redis采用了AOF和RDB两种持久化方式,将用户数据以特殊形式保存在磁盘中,确保重启时可以恢复之前的内存数据状态

AOF(Append Only File)日志

redis的AOF持久化方式是:redis每执行一次写操作,就将对应的命令记录到一个磁盘文件中,redis一旦宕机,重启时重新执行这些命令就可以恢复之前的数据状态

在这里插入图片描述

这种保存写操作命令到日志的持久化方式,就是 Redis 里的 AOF(Append Only File) 持久化功能

写日志的步骤:

1.写入aof内核缓冲区

2.将内核缓冲区的数据写入磁盘

Redis 是先执行写操作命令后,才将该命令记录到 AOF 日志里的,这么做其实有两个好处:

1.避免额外的检查,如果一条命令不符合协议的语法,那么这条语句是不会被执行的,如果先写入日志,就会导致恢复数据时,这条命令失效,造成了不必要的性能开销

2.不会阻塞当前写操作的执行,因为执行命令和写日志两个操作都是由主进程进行的,先保证写操作的执行,再进行写日志

AOF持久化的缺陷

1.由于执行写操作和写日志是两个串行的操作,如果在写入日志之前redis故障,就会导致数据丢失

2.写日志操作虽然不会阻塞上一个写操作的执行,但是会阻塞下一个写操作的执行

在这里插入图片描述

问题根源——写日志的时机

我们刚刚介绍的,先执行写操作,随后写日志其实是redis日志写策略的一种,现在介绍redis提供的写日志的三种策略

1.Always:每次进行写操作后,将命令写入aof内核缓冲区,随即写入磁盘

2.Everysec:每次进行写操作后,将命令写入aof内核缓冲区,每隔一秒将数据写入磁盘

3.NO:每次进行写操作后将命令写入aof内核缓冲区,由操作系统决定写磁盘的时机

不难发现,每次进行写操作后都必须将命令写入内核aof内核缓冲区,这个过程并不耗时,容易造成阻塞的是写磁盘操作

三种策略的优缺点:

在这里插入图片描述

操作系统何时将aof缓冲区的数据写入磁盘?

当应用程序向文件写入数据时,内核通常先将数据复制到内核缓冲区中,然后排入队列,然后由内核决定何时写入硬盘,也就是说,内核缓冲区不止由aof的数据,还有其它的数据,真正的写磁盘时机由操作系统的策略决定

写磁盘时机可以由程序员决定吗?
fsync函数是操作系统提供的同步函数,可以强制让操作系统立即将内核缓冲区的数据写入到磁盘中
上面提到的 Always和Everysec两种写磁盘策略本质上就是调用了fsync函数

AOF重写机制

聪明的你,有没有发现AOF日志会记录一些无效信息?

比如,我执行了set name wjq,随后又执行了set name wjq++,此时数据库中name对应的值实际上是wjq++,而wjq这个值被覆盖了,是无效的,而AOF全部记录了这两条命令,并在恢复数据时重新执行这两条命令,而实际上只需要记录第二条命令,这无疑造成了性能浪费

那么,如何判断某条命令(set name wjq)可以不被记录呢?

很简单,只要查看数据库中现有的数据(wjq++),其中的数据是恢复时所必需的

所以,AOF重写机制就是

读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到「新的 AOF 文件」,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。

重写工作完成后,就会将新的 AOF 文件覆盖现有的 AOF 文件,这就相当于压缩了 AOF 文件,使得 AOF 文件体积变小了。

AOF后台重写

之所以使用AOF重写机制,不是因为AOF记录了无效的信息,而是因为当数据量过大时,AOF文件占用空间过多,我们需要将AOF文件进行压缩

所以,AOF重写机制的触发时机是:当 AOF 文件大于 64M 时

触发 AOF 重写时,比如当 AOF 文件大于 64M 时,就会对 AOF 文件进行重写,这时是需要读取所有缓存的键值对数据,并为每个键值对生成一条命令,然后将其写入到新的 AOF 文件,重写完后,就把现在的 AOF 文件替换掉

你有没有发现,在正常的AOF日志写操作时,是对每一条命令写入aof缓冲区,这个过程并不耗时

但AOF重写时,AOF文件已经超过了64M,这时进行生成命令、写入新文件的操作相当耗时,万万不能放在主进程中进行,那怎么办呢?

所以,Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的

当需要进行AOF重写时,fork出一个子进程,由子进程执行重写操作,这样就不会阻塞主进程了

重写期间数据不一致的问题

考虑这样的情况:在子进程进行AOF重写操作时,主进程添加或修改了新的数据,这时子进程只拥有fork时刻的父进程的副本,而没有新添加的数据,并且在AOF重写完成后会用新AOF文件覆盖旧的AOF文件,也就是说,这种数据不一致会导致AOF重写期间添加和修改的数据丢失

解决:

既然在AOF重写期间的新数据只会出现在父进程,而不会出现在子进程,那我们将新数据追加到子进程不就好了

方案:

父进程拥有aof缓冲区

子进程拥有aof重写缓冲区

1.先执行客户端发送的写操作命令

2.将命令写入父进程aof缓冲区

3.将命令写入子进程aof重写缓冲区

这样就解决了父子进程数据不一致和数据丢失的问题

总结

1.AOF日志的持久化具体过程:每执行一条写命令,将该命令写入aof缓冲区,然后由三种写策略(always、everysec、no)决定何时将aof缓冲区数据写入磁盘文件

2.在数据库恢复时,重放磁盘中AOF文件中保存的命令,就实现了内存数据的恢复

3.由于aof记录每一条写命令,会造成记录无效数据的情况,并且数据量大时,aof文件的体积也会过大

为缓解aof的空间占用,redis设计了aof重写的机制,它会扫描数据库中的键值对,并为之生成命令,写入一个新的aof文件中,全部键值对写入完成后,新的aof文件会覆盖旧aof文件,这个过程避免了无效命令的记录,压缩了aof文件体积

大时,aof文件的体积也会过大

为缓解aof的空间占用,redis设计了aof重写的机制,它会扫描数据库中的键值对,并为之生成命令,写入一个新的aof文件中,全部键值对写入完成后,新的aof文件会覆盖旧aof文件,这个过程避免了无效命令的记录,压缩了aof文件体积

不过由于执行aof重写操作的时机是旧aof文件超过64M,也就是说aof重写操作将会很耗时,redis使用一个fork出的子进程来执行这个任务,但是在子进程进行aof重写时,如果父进程产生了新aof数据,会造成数据不一致,且在子进程完成aof重写并覆盖旧aof文件后,这些多出的不一致数据会丢失,所以在aof重写期间追加的新aof数据会先写入父进程aof缓冲区,再写入子进程aof重写缓冲区,解决了数据不一致和数据丢失的问题

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

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

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

相关文章

SQL笔记——表的操作、数据修改、列的属性和查询操作

表的操作 在之前应该有一个数据库 先创建一个 user 库,然后可以查看、修改、删除 create databases user;//创建 show databases; //展示 alter databases user //修改 修改的内容; drop databases user1;//删除 或者是 drop databases if exists user1;添加数据之前肯定要知…

java基础-IDEA环境基础用法自动导包等设置

IDEA: 是用于Java语言开发的集成环境,它是业界公认的目前用于Java程序开发最好的工具。 把代码编写,编译,执行,调试等多种功能综合到一起的开发工具。 IDEA项目结构: 多级包用 . 链接。 快速生成 快…

STM32的通用定时器中断编程

如果遇到需要单片机产生严格时序的场景(比如DAC输出特定模拟信号,GPIO口控制模拟开关),延时函数可能就无法胜任了。最近在工作时公司上级教会了我使用“门票”思维(中断标志位)编写单片机裸机程序,今天写一…

JAVA 替代SWITCH 枚举值 CASE 的 策略模式

看看使用策略模式之前的代码&#xff1a; // switch (type) { // case 0: // terme.setKhdmlist(dmList); // List<Kehu> list getSdList$api(terme); // for (Kehu kehu : list) { // …

论文学习_Large Language Models Based Fuzzing Techniques: A Survey

论文名称发表时间发表期刊期刊等级研究单位 Large Language Models Based Fuzzing Techniques: A Survey 2024年arXiv- 悉尼大学 0.摘要 研究背景在软件发挥举足轻重作用的现代社会&#xff0c;软件安全和漏洞分析对软件开发至关重要&#xff0c;模糊测试作为一种高效的软件…

前端学习-day10

文章目录 01-体验平面转换02-平移效果03-绝对定位元素居中04-案例-双开门06-转换旋转中心点07-案例-时钟-转换原点08-平面转换-多重转换09-缩放效果10-案例-按钮缩放11-倾斜效果12-渐变-线性13-案例-产品展示14-渐变-径向15-综合案例-喜马拉雅 01-体验平面转换 <!DOCTYPE h…

2024.6.17总结1113

今天早上进行了毕设答辩&#xff0c;无论是打印报告还是答辩&#xff0c;整个过程都挺顺利的。 其实&#xff0c;昨天还是挺慌的&#xff0c;就觉得自己的论文还存在许多问题&#xff0c;但是&#xff0c;早上看到那么多人的论文都存在这样那样的问题的时候&#xff0c;我反而…

Spring框架的原理及应用详解(七)

本系列文章简介&#xff1a; 在当今的软件开发世界中&#xff0c;随着应用复杂性的不断增加和技术的快速发展&#xff0c;传统的编程方式已经难以满足快速迭代、高可扩展性和易于维护的需求。为此&#xff0c;开发者们一直在寻求更加高效、灵活且易于管理的开发框架&#xff0c…

C#(C Sharp)学习笔记_多态【十九】

前言 个人觉得多态在面向对象编程中还比较重要的&#xff0c;而且不容易理解。也是学了一个下午&#xff0c;才把笔记写得相对比较完善&#xff0c;但仍欠缺一些内容。慢慢来吧…… 什么是多态&#xff1f; 基本概念 在编程语言和类型论中&#xff0c;多态&#xff08;Poly…

C# + easyui 写的一个web项目

用C# easyui 来开发&#xff0c;其实就是为了开发速度&#xff0c;用easyui可以一天写很多页面&#xff0c;比一些低代码平台还快。 登陆页面 主界面 记录数统计 家庭信息采集表 新建家庭 家庭成员 低保、五保人员帮扶情况登记表 低保、五保人员帮扶情况登记表的新增和编辑 治…

【UE数字孪生学习笔记】 Gameplay框架之TSubclassOf

声明&#xff1a;部分内容来自于b站&#xff0c;知乎&#xff0c;慕课&#xff0c;公开课等的课件&#xff0c;仅供学习使用。如有问题&#xff0c;请联系删除。 部分内容来自UE官方文档&#xff0c;博客等 TSubclassOf TSubclassOf 是一个模板类&#xff0c;用于存储对某个特…

科研辅助工具

科研工具收集 1. 如何筛选出最合适的SCI论文投稿杂志:点击直达 2. 分享三种正确查找期刊全称、缩写的网站: 点击直达

(done) AFL 都有哪些阶段? Stage progress

参考资料&#xff1a;https://afl-1.readthedocs.io/en/latest/user_guide.html 所有阶段如下&#xff0c;包括详细的解释

论文《Dual-Contrastive for Federated Social Recommendation》阅读

论文《Dual-Contrastive for Federated Social Recommendation》阅读 论文概况MotivationMethodologyClient Local ComputingCenter Server Aggregation 总结 今天简单总结一下一篇关于联邦推荐方面的论文《Dual-Contrastive for Federated Social Recommendation》&#xff0c…

Java | Leetcode Java题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; class Solution {public int findPeakElement(int[] nums) {int n nums.length;int left 0, right n - 1, ans -1;while (left < right) {int mid (left right) / 2;if (compare(nums, mid - 1, mid) < 0 && compare(n…

【Linux 内存管理】

文章目录 1. 为什么要有虚拟内存呢&#xff1f;&#x1f50d; 1. 为什么要有虚拟内存呢&#xff1f;&#x1f50d;

如何实现element表格合并行?

前两天我一个朋友咨询我element表格合并行的问题,他研究了很久,已经开始怀疑是不是element UI出现了bug,然后跟我一阵沟通,最终解决了问题,他的问题在于他把事情想复杂了,接下来我们一起来看一下这个经典“案例”,很多人真的很有可能走入这个误区,当然老鸟就不用看了,…

读AI新生:破解人机共存密码笔记04计算的极限

1. 计算的极限 1.1. 光靠速度是无法给我们带来人工智能的 1.1.1. 在速度更快的计算机上运行糟糕的算法并不会使算法变得更优秀&#xff0c;这只意味着你会更快地得到错误的答案 1.1.2. 数据越多&#xff0c;错误答案出现的机会就越大 1.…

pytorch基础【3】torch运算

文章目录 torch运算基本运算形状操作自动调整size (参数-1) 数学运算逻辑运算常见的高级操作随机数生成 torch运算 基本运算 创建张量: import torch# 直接从列表或数组创建张量 x torch.tensor([1, 2, 3])创建特定值的张量: # 全零张量 zeros torch.zeros(3, 3)# 全一张量 …

python调用SDK的问题

问题&#xff1a;Could not find module MvCameraControl.dll 原因&#xff1a;识别环境变量runtime异常 解决&#xff1a;指定具体绝对地址即可。MvCameraControl.dll的位置C:\Program Files (x86)\Common Files\MVS\Runtime\Win64_x64 MvCamCtrldll WinDLL("MvCamer…