关于Redis的持久化

Redis与MySQL的不同

MySQL的事务,有四个核心特性:原子性、一致性、持久性和隔离性

把数据存储在磁盘上就是持久化的,把数据存储在内存上则是不持久化的。区别在于重启进程/主机后,数据是否存在。

而Redis是一个内存数据库,是把数据存储在内存中的!!!

而相较于MySQL,Redis最大的优势就是快、效率高

但是如果要保证数据的持久化,就必须要把数据写入磁盘,但又不能破坏掉Redis的高效,所以Redis采用以下策略:

  • 插入一个新数据的时候,需要把这份数据同时写入内存和磁盘

  • 查询某个数据的时候,直接从内存中读取

  • 硬盘中的数据只是在Redis重启的时候,用来恢复内存中的数据的

这样做的代价就是消耗了更多的空间,但是硬盘比较便宜,这样的开销并不会带来太多成本。

问题在于,Redis查询数据时访问内存,效率确实快很多,可是插入数据时,既要写内存又要写硬盘,多了IO操作,该怎么保证效率?

Redis持久化的策略

RDB(Redis DataBase) 定期备份

定期地把Redis内存中的所有数据,都写入硬盘中,生成一个“快照”,后续Redis一旦重启,就可以根据快照恢复内存数据

手动触发

程序员通过Redis客户端,执行特定的命令(save、bgsave),触发生成快照

  • save命令在前台进行,执行时会全力以赴地进行生成快照的操作,会阻塞其他的客户端命令,造成类似于keys*的效果

  • bgsave在后台进行,并不影响其他客户端请求,注意这里是采用多进程的方式完成并发编程,Redis中没有多线程

bgsave的工作流程:

当父进程也就是Redis服务器收到一个bgsave的命令,会先判定当前是否已经存在其他正在工作的子进程,如果当前已经有一个子进程在执行bgsave,就直接把当前的bgsave命令返回,否则就创建一个子进程执行bgsave,也就是Redis中任何时候只能有一个客户端执行bgsave。子进程完成整体的持久化过程之后,会通知父进程,父进程进行一些统计信息的更新,随后销毁子进程。

执行RDB会生成一个镜像文件dump.rdb,把内存中的数据以压缩的形式保存到该二进制文件中,虽然需要消耗一定的CPU资源,但是可以节省存储空间

RDB持久化操作是可以触发多次的,在已经存在dump.rdb 文件的情况下再进行rdb操作,会先把要生成的快照数据保存在一个临时文件中,快照生成完毕后会删除之前的rdb文件,再把临时文件名称改为dump.rdb,自始至终都只有一个dump.rdb文件

自动触发

在Redis配置文件中,设置让Redis每隔多长时间/每产生多少次修改就触发生成快照

但因为生成快照的操作不能太频繁,所以快照数据和实时数据可能会存在偏差,所以在不满足生成快照条件的时候,如果Redis服务器挂了,就会导致一部分数据丢失

但是Redis的自动触发生成快照不仅可以通过配置文件的方式,还可以通过Redis的shutdown命令触发,当Redis进行主从复制的时候,主节点也会自动生成rdb快照,然后把rdb快照文件内容传输给从节点。

注意,如果是通过正常流程重新启动Redis服务器,此时Redis服务器会在提出的时候,自动触发生成rdb操作,但如果是异常重启(kill -9 或者 服务器掉电),服务器就来不及生成rdb,此时内存中尚未保存到快照中的数据就会丢失

总结:

  • Redis采用rdb生成快照的操作要对内存中所有数据进行保存,所以适用于全量数据保存的情况

  • 由于rdb操作最终保存的二进制,所以加载数据时要快于AOF(用文本的形式保存)

  • RDB方式没有办法做到实时持久化/秒级持久化,因为bgsave每次执行都要执行fork创建子进程,属于重量级操作,频繁操作成本过高

  • RDB文件使用二进制格式保存,Redis版本演进过程中会有多个RDB版本,兼容性可能会有风险

RDB最大的问题就是,不能实时的持久化保存数据,在两次生成快照之间,实时的数据可能会随着重启而丢失。

AOF(Append Only File) 实时备份

AOF的保存数据方式类似于MySQL中的 binlog,会把用户的每个操作,记录在文件中,当Redis重启的时候,就会读取这个aof文件中的内容,用来恢复数据(当开启aof的时候,就默认rdb失效,不再读取rdb文件中的内容)

还是和RDB同样的问题,Redis把操作写进aof文件,又要写内存,又要写磁盘,怎么保证速度?

  1. AOF机制并非是直接让工作线程把数据写入硬盘,而是先写入一个内存中的缓冲区,积累到一定量之后,再统一写进硬盘

  2. AOF每次都会把新的操作写到原有文件内容的末尾,属于顺序写入,硬盘上读写数据,顺序读写的速度比随机要快(当然还是比内存慢)

跟RDB相同,如果在内存缓冲区中的数据量不够刷新到磁盘时,出现了服务器掉电的情况,这部分数据就会丢失。所以,针对这个情况,Redis给出了一些选项供程序员选择(在刷新频率和效率之间做一个抉择),就像MySQL中的事务隔离级别,安全性和效率往往不能兼顾

Redis的重写机制(rewrite)

对于AOF备份,当操作越来越多,AOF文件的体积就越来越大,虽说磁盘空间不值钱,但是在Redis重启加载数据的时候会有很大的消耗,而且AOF中很可能有一些数据时冗余的(比如先插入数据,再删除数据,实际上Redis关注的只是数据最后的状态)

所以Redis中有一个机制,可以对AOF文件中的冗余信息进行缩减,达成“瘦身”的效果,也就是重写机制。

AOF重写和RDB一样也分为手动和自动,大致原理相同,不再赘述。

AOF重写流程:

创建子进程,父进程仍然负责接收请求,子进程负责对AOF文件进行重写,重写过程中不关心原来的AOF文件中的所有操作记录,只关心当前内存中的数据状态,把当前最新的数据状态以AOF的形式写入一个新文件,把原有的AOF文件删除,再把新文件改为AOF即可

在父进程创建子进程之后,子进程重写之间,父进程可能还会接收到新的请求,这时还会往旧的AOF文件中写入数据,当子进程重写完成后覆盖原有的AOF文件,新写入的数据不就丢失了吗?

为了避免这个情况,Redis的AOF重写机制中,父进程创建完子进程之后,会有另外一个aof_rewrite_buf缓冲区,用于存放fork之后收到的数据。这时父进程收到的新的数据不仅要写入原来的AOF文件,还要写入这个缓冲区,当子进程完成重写之后会通过信号 通知父进程,父进程就会把缓冲区中的内容页写入新的AOF文件中。

特殊情况:

  • 如果在执行bgrewriteaof的时候,发现当前Redis正在进行AOF重写,此时就不会再次执行AOF重写,直接返回

  • 如果在执行bgrewriteaof的时候,发现当前Redis正在生成rdb快照,此时AOF重写操作就会等待rdb快照生成完毕之后,再进行AOF重写

这里可以发现,RDB和AOF的不同,RDB对于fork之后的数据,就直接置之不理了,并不会采用rewrite_buf的方式来处理。

RDB本身的设计理念就是用来“定期备份”的,只要是定期备份,就难以和最新的数据保持一致,但定期备份和实时备份没有绝对的谁好谁坏,还是要看具体的使用场景

既然父进程fork之后,子进程就会往新的AOF文件中写入数据,那么父进程只需要往aof_rewrite_buf中写入数据就行了,为什么还要向旧的AOF文件中写?

考虑极端情况,子进程重写AOF过程中,服务器挂了,子进程内存中的数据就会丢失,新的AOF文件内容还不完整,这时需要父进程中旧的AOF文件保证数据的完整性。

但是,AOF文件并不是任何时候都只有文本类型的数据,可能还包含二进制数据。因为文本的方式写文件,后续的加载成本比较高。于是,Redis引入了“混合持久化”的方式,结合了rdb 和 aof 的特点。针对每一个请求/操作,按照AOF的方式记录进文件;在触发AOF重写之后,会把当前内存中的状态按照RDB的二进制格式写入新的AOF文件中;后续有新的操作,仍然是按照AOF文本的方式追加到文件后面。

当Redis中同时存在AOF文件和RDB快照的时候,以AOF为主,RDB直接忽略,因为AOF中的数据更全

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

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

相关文章

Avalonia TreeView 示例代码

参考文档 https://docs.avaloniaui.net/docs/reference/controls/detailed-reference/treeview-1 新建一个avalonia MVVM工程AvaloniaAppTreeview&#xff0c;删掉MainWindow.xaml里的<TextBlock Text"{Binding Greeting}" HorizontalAlignment"Center"…

数据可视化:Matplotlib 与 Seaborn

数据可视化是数据分析中至关重要的一部分&#xff0c;它能帮助我们直观地理解数据的分布、趋势和关系。Python 中&#xff0c;Matplotlib 和 Seaborn 是两个最常用的可视化库。本文将详细介绍如何使用 Matplotlib 和 Seaborn 进行数据可视化&#xff0c;包括基本图形、图形定制…

Spring boot项目

一. Spring boot 安装地址 https://start.spring.io/ 二. 选择 三. idea配置 找到下载的文件解压缩&#xff0c;打开pom.xml(选择从idea打开)

ROS基础学习-ROS通信机制进阶

ROS通信机制进阶 目录 0.简介1.常用API1.1 节点初始化函数1.1.1 C++1.1.2 Python1.2 话题与服务相关函数1.2.1 对象获取相关1.2.1.1 C++1.2.1.2 Python1.2.2 订阅对象相关1.2.2.1 C++1.2.2.2 Python1.2.3 服务对象相关函数1.2.3.1 C++1.2.3.2 Python1.2.4 客户端对象相关1.2.4.…

推荐一个网安资源学习网站

渗透师 网络安全从业者安全导航 工具 wireshark metasploit namp sqlmap 国外安全论坛 hack forums Форум АНТИЧАТ Tuts 4 You 安全帮网址导航 | 让网络安全资源更有序&#xff01; src挖掘

常见机器学习概念

信息熵 信息熵&#xff08;information entropy&#xff09;是信息论的基本概念。描述信息源各可能事件发生的不确定性。20世纪40年代&#xff0c;香农&#xff08;C.E.Shannon&#xff09;借鉴了热力学的概念&#xff0c;把信息中排除了冗余后的平均信息量称为“信息熵”&…

Python的Pillow(图像处理库)的一些学习笔记

Python的Pillow库是一个非常强大的图像处理库。 安装Pillow库&#xff1a; 在终端或命令行中输入以下命令来安装Pillow&#xff1a; pip install pillow 升级库&#xff1a; pip install pillow --upgrade 一些基础的应用 1、图像文件方面的&#xff1a; 打开文件 …

LVS负载均衡群集+NAT部署

目录 1.企业群集应用概述 1.1 群集的含义 1.2 企业群集分类 2.LVS负载均衡群集运用理论 2.1 负载均衡的架构 2.2 LVS负载均衡群集工作的三种模式 3.LVS虚拟服务器&#xff08;Linux Virtual Server&#xff09; 3.1 ip_vs通用模块 3.2 LVS调度器用的调度方法 4.ipvs…

【CS.DB】深度解析:ClickHouse与Elasticsearch在大数据分析中的应用与优化

文章目录 《深入对比&#xff1a;在大数据分析中的 ClickHouse和Elasticsearch》 1 介绍 2 深入非关系型数据库的世界2.1 非关系型数据库的种类2.2 列存储数据库&#xff08;如ClickHouse&#xff09;2.3 搜索引擎&#xff08;如Elasticsearch&#xff09;2.4 核心优势的归纳 3…

面试高频问题----5

一、线程池参数的执行顺序 1.如果线程池中的线程数量小于核心线程数&#xff0c;则创建新的线程来处理任务 2.如果线程池中的线程数量等于核心线程数&#xff0c;但工作队列未满&#xff0c;将任务放入工作队列中执行 3.如果工作队列已满&#xff0c;但线程数小于最大线程数…

01_基于人脸的常见表情识别实战_深度学习基础知识

1. 感知机 感知机通常情况下指单层的人工神经网络,其结构与 MP 模型类似(按照生物神经元的结构和工作原理造出来的一个抽象和简化了模型,也称为神经网络的一个处理单元) 假设由一个 n 维的单层感知机,则: x 1 x_1 x1​ 至 x n x_n xn​ 为 n 维输入向量的各个分量w 1 j…

《C++避坑神器·二十七》VS中release打断点方法,#undef作用

1、release打断点方式 2、#undef作用 #undef指令用于”取消“已定义的#define指令 案例&#xff1a;

UiPath发送邮件给多人时需要注意哪些限制?

UiPath发送邮件给多人的步骤&#xff1f;如何使用UiPath发信&#xff1f; 尽管UiPath提供了强大的邮件发送功能&#xff0c;但在批量发送邮件时&#xff0c;有一些限制和注意事项是我们必须了解的。AokSend将详细介绍这些限制&#xff0c;并提供一些优化建议。 UiPath发送邮件…

深度解析:全流量分析与IP会话回溯在IT运维中的应用

目录 什么是全流量分析&#xff1f; 全流量分析的优势 实际应用案例 IP会话回溯&#xff1a;精准故障排除的利器 IP会话回溯的工作原理 案例分享&#xff1a;快速解决网络故障 全流量分析与IP会话回溯的结合 IT运维中的实用技巧 总结 在现代IT运维中&#xff0c;网络的…

dependencies?devDependencies?peerDependencies

之前使用的npm包中&#xff0c;我用到了sass包。我当时没有在packagejson中添加依赖项&#xff0c;而是另外install的。这就引起了我的一个思考 初步想法&#xff1a; 我的npm包需要使用sass&#xff0c;那么我应该放在dependencies中&#xff0c;当使用的时候会直接下载 问题…

【SQLAlChemy】如何定义ORM模型,如何映射到数据库?

定义ORM模型并映射到数据库 创建 ORM 基类 使用 declarative_base 根据 engine 来创建一个 ORM 基类。 from SqlAIchemy.LinkDB.main import engineBase declarative_base()创建自定义类 用上边定义的 Base 类来实现自己的 ORM 类。 __tablename__ 类属性&#xff0c;可以…

Electron qt开发教程

模块安装打包 npm install -g electron-forge electron-forge init my-project --templatevue npm start //进入目录启动 //打包成一个目录到out目录下&#xff0c;注意这种打包一般用于调试&#xff0c;并不是用于分发 npm run package //打出真正的分发包&#xff0c;放在o…

Swift 序列(Sequence)排序面面俱到 - 从过去到现在(二)

概览 在上篇 Swift 序列(Sequence)排序面面俱到 - 从过去到现在(一)博文中,我们讨论了 Swift 语言中序列和集合元素排序的一些基本知识,我们还给出了以自定义类型中任意属性排序的“康庄大道”。 不过在实际的撸码场景中,我们往往需要的是“多属性”同时参与到排序的考…

工业楼控暖通组态恒温检测控制大屏前端UI案例

工业楼控暖通组态恒温检测控制大屏前端UI案例

U盘文件系统结构损坏的应对与预防

在数字化时代&#xff0c;U盘作为便携式存储设备&#xff0c;其重要性不言而喻。然而&#xff0c;当U盘文件系统结构损坏时&#xff0c;我们可能会面临数据丢失的风险。本文将深入探讨U盘文件系统结构损坏的问题&#xff0c;分析其产生的原因&#xff0c;并给出相应的数据恢复方…