Redis持久化

持久化是什么

额 就是永久化的保存数据呗

有两种持久化方式RDB和AOF
1.RDB (Redis Database),记录Redis某 个时刻的全部数据,这种方式本质就是数据快照,直接保存二进制数据到磁盘,后续通过加载RDB文件恢复数据。

2.AOF (Append Only File) ,记录执行的每条命令,重启之后通过重放命令来恢复数据,AOF本质是记录操作日志,后续通过日志重放恢复数据。

仅从他们的性质来看

RDB是快照恢复,AOF是日志恢复
体积方面:相同数据量下,RDB体积更小,因为RDB是记录的二进制紧凑型数据
恢复速度: RDB是数据快照,可以直接加载,而AOF文件恢复,相当于重放情况,RDB显然会更快
数据完整性: AOF记录了每条日志,RDB是间隔一段时间记录一次,用AOF恢复数据通常会更为完整。

如果业务本身只是缓存数据且并不是一个海 量访问,可以不用开持久化。
如果对数据非常重视,可以同时开启RDB和AOF, 注意一点,同时开启的情况下,只会用AOF来加载,同时开启了AOF和RDB表示对数据要求强一致 如果AOF不存在 那就回启动空库 不会用RDB恢复数据 因为RDB可能会缺少很多数据

如果可以接受丢几分钟级别的数据,那么建议只开RDB。

 Redis官方不建议单独开AOF,因为如果决定要走数据备份,那么镜像保存始终是数据库领域非常行之有效的解决方案,所以在配置中RDB是默认打开的,而AOF不是。(有比没有强)

细说RDB

触发RDB的条件


每900s,有1条写数据操作;
每300s,有10条写数据操作;
每60s,有10000写数据操作。

写数据操作指增加、删除、更新
他们之间是并集关系,即只要满足其中一个条件,就达到了RDB持久化的条件,这里用的bgsave不是save 省的阻塞 

什么时候进行持久化

1.主动执行save

执行了save 命令,就会在主线程生成RDB文件由于和执行操作命令在同一个线程,所以如果写入RDB文件的时间太长,会阻塞主线程,这个命令慎用。

2.主动执行bgsave

和save不同,会创建一个子 进程来生成RDB文件,这样可以避免主线程的阻塞。

3.达到持久化配置阈值
上面有提到,Redis可以配置持久化策略,达到策略就会触发持久化,这里的持久化使用的方式是后台save,从这可以看到Redis比较推荐的方式也是后台执行持久化,尽可能减少对主流程影响。达到阈值之后,是由周期函数触发持久化。

4.还会在程序正常关闭的时候执行
在关闭时,Redis会启动- -次阻塞式持久化,以记录更全的数据

RDB具体做了什么

就是这样,Redis使用bgsave对当前内存中的所有数据做快照,这个操作是由bgsave子进程在后台完成的,执行时不会阻塞父进程中的主线程,这就使得主线程同时可以修改数据。
这样的目的是为了减少创建子进程时的性能损耗,从而加快创建子进程的速度,毕竟创建子进程的过程中,是会阻塞主线程的。
可以看到,复制期间,读数据互不影响,如果有写操作发生,则主进程复制一-份内存,在这个复制的内存基础上,主进程再修改原来的数据,子进程持久化的依然是修改之前的数据。

1.RDB本质是什么? 

RDB本质是二进制形式的快照。

2.如何开始RDB

RDB可以通过配置定时触发,触发时用的是后台持久化方式。
也可以save命令,bgsave命令 主动触发,save底层用的是阻塞式持久化,bgsave用的是后台持久化。
实际生产中,很少会自己主动执行命令(这句话实力强点,有底气才说)
最后,如果Redis正常关闭,是会执行阻塞式持久化的。


3.RDB对主流程有什么影响?
 

 当执行阻塞式持久化的时候,由主进程进行RDB快照保存,会阻塞主进程
当执行后台持久化时,由fork出的子进程来进行RDB快照保存
。如果数据量比较大的时候,会导致fork子进程这个操作比较耗时,从而阻塞主进程
。由于采用了写时复制技术,如果在进行RDB快照保存的时候,有大量的写入操作执行,会导致主进程多拷贝一份数据,消耗大量额外的内存

4.RDB执行流程是怎样的?

首先,Fork出-个子进程来专门做RDB持久化
接着,子进程写数据到临时的RDB文件
最后,用新RDB文件替换旧的RDB文件

具体来讲

打开一个临时的RDB文件(c语 言库函数fopen)
将执行命令这一 时刻数据库数据写入到I0缓冲区(c语言库函数fwrite) 会将这一时刻的数据按照RDB对应的版本格式进行写入
执行fush (将IO缓冲区里的数据刷新到内核缓冲区)
执行fsync (可以将内核缓冲区里的数据刷到磁盘)
执行fclose (关闭这个临时文件)
修改临时文件名字,并让咱们的后台线程BIO_ _LAZY_ FREE去删除旧的RDB (到此一次RDB过程结束)
简单来说RDB的流程就是 触发RDB持久化时,让主进程或子进程(区分条件)来将这一-时刻的数据库数据写到一个新的RDB文件中.
 

细说AOF

刚才说了 RDB是默认打开的 AOF要自己手动开启

打开Redis的配置文件

/usr/local/etc/redis.conf

打开之后,Redis每条更改数据的操作都会记录到AOF文件中,当你重启,AOF会助你重建状态,相当于就是请求全部重放一次,所以AOF恢复起来会比较慢。
 

AOF写入流程

 这不免会让人担心,是否会影响Redis的执行性能,答案是肯定的,多了一步操作,或多或少都会带来些损耗,但是Redis实际是提供了不同的策略来选择不同程度的损耗。这里我们先从比较的宏观视角,介绍Redis提供的3种刷盘
策略,以便根据需要进行不同的选择。
1.appendfsync always, 每次请求都刷入AOF,用官方的话说,非常慢,非常安全
2.appendfsync everysec,每秒刷一次盘,用官方的话来说就是足够快了,但是在崩溃场景下你可能会丢失1秒的数据。
3.appendfsync no,不主动刷盘,让操作系统自己刷,一般情况Linux会每30秒刷一 -次盘,这种策略下,可以说对性能的影响最小,但是如果发生崩溃,可能会丢失相对比较多的数据。

 经典给三种选择 然后推荐使用中间的

写入操作具体行为

写入AOF,其实是分了好几步来的。
第一步:其实是将数据写入AOF缓存中,这个缓存名字是aof_ _buf, 其实就是一个sds数据

第二步: aof_ buf对应数据刷入磁盘缓冲区,什么时候做这个事情呢?事实上,Redis源码中一共有4个时机,会调用一个叫flushAppendOnlyFile的函数,这个函数会使用write函数来将数据写入操作系统缓冲区:
1.处理完事件处理后,等待下一次事件到来之前,也就是beforeSleep中 。
2.周期函数serverCron中,这也是我们打过很多次交道的老朋友了
3.服务器退出之前的准备I作时
4.通过配置指令关闭AOF功能时

第三步:刷盘,即调用系统的flush函数,刷盘其实还是在flushAppendOnlyFile函数中,是在write之后, 但是不一定调用了flushAppendOnlyFile,flush就一定会被调用,这里其实是支持一个刷盘时机的配置, 这一 步受 刷盘策略影响是最深的,如下面代码所示,如果是appendfsync always策略,那么就立刻调用redis_ fsync刷盘, 如果是AOF_ FSYNC_ EVERYSEC策略,满足条件后会用aof_ background_ fsync使用后 台线程异步刷盘。

AOF重写

 
AOF是不断写入的,这很容易带来一个疑问, 如此下去AOF不是会不断膨胀吗?
针对这个问题,Redis采用了重写的方式来解决:
Redis可以在AOF文件体积变得过大时,自动地在后台Fork-个子进程,专门对AOF进行重写。说白了,就是针对相同Key的操作,进行合并,比如同一个Key的set操作,那就是后面要盖前面。
在重写过程中,Redis不但将新的操作记录在原有的AOF缓冲区,而且还会记录在AOF重写缓冲区。一旦新AOF文件创建完毕,Redis 就会将重写缓冲区内容,追加到新的AOF文件,再用新AOF文件替换原来的AOF文件。

达到多大开始重写是配置文件决定的

超过64M的情况下,相比上次重写时的数据大一倍,则触发重写,很明显,最后实际上还是在周期函数来检查和触发的。
 这两个参数可以修改

简述AOF重写流程

可以将AOF重写流程记为"一次拷贝,两处日志”
一次拷贝:重写发生时,主进程会fork出一个子进程, 让子进程将这些Redis数据写入重写日志
两处日志:重写发生时,我们需要注意AOF缓冲和AOF重写缓冲;当重写时,有新的写入命令执行,会由主进程分别写入AOF缓冲和AOF重写缓冲; AOF缓冲用于保证此时发生宕机,原来的AOF日志也是完整的,可用于恢复。AOF重写缓冲 用于保证新的AOF文件也不会丢失最新的写入操作。
额外补充:在重写时AOF重写缓冲会通过管道传送给子进程,再由子进程刷入新的AOF日志(此时,AOF重写完成)
 

AOF混合持久化

混合部署听名字似乎是同时开启RDB和AOF,实际上不是的,混合部署实际发生在AOF重写阶段,将当前状态保存为RDB二进制内容,写入新的AOF文件,再将重写缓冲区的内容追加到新的AOF文件,最后替代原有的AOF文件。此时的AOF文件,就不再单纯的是日志数据,而是二进制数据+日志数据的混合体,所以叫混合持久化。(流程没变 只是日志文件变了)

它解决了什么问题


混合持久化是是发生在原有的AOF流程,如果从这个视角来看,其实本质还是AOF,只是重写时使用了RDB进行了优化。
混合持久化是对AOF重写的优化,这种方式可以大大降低AOF重写的性能损耗。以及降低AOF文件的存储空间,付出的代价则是降低AOF文件的读写行,但是实际生产中,很少有真正需要去人肉读AOF数据的情况,这点从5.0之后默认打开AOF混合持久化模式也能看出。
在我看来,如果是考虑到对Redis核心处理性能的影响,那还是需要用RDB,如果是为了相对更可靠的数据记录,也就是尽可能丢失更少的数据,那还是得用AOF,同时,如果对可读性没有太大执念,那进一步开启混合持久化。 是一个很好的选择,毕竟其实生产上,关注AOF可读性的情况实际比较少。

混合持久化开启之后,服务启动时如何加载持久化数据

之前有说过,如果同时启用了AOF和RDB,Redis 重新启动时,会使用AOF文件来重建数据集,因为通常来说,
AOF的数据会更完整,那这里其实是一样的, 混合持久化还是属于AOF,所以如果有混合持久化,那肯定是优先使用混合持久化的数据。

混合持久化的A0F文件里开头有REDIS这个标记,加载时候通过这个标记来进行的判断
 

 


 

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

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

相关文章

项目介绍:《WeTalk》网页聊天室 — Spring Boot、MyBatis、MySQL和WebSocket的奇妙融合

目录 引言: 前言: 技术栈: 主要功能: 功能详解: 1. 用户注册与登录: 2. 添加好友 3. 实时聊天 4. 消息未读 5. 删除聊天记录 6. 删除好友 未来展望: 项目地址: 结语&am…

Golang服务的请求调度

文章目录 1. 写在前面2. SheddingHandler的实现原理3. 相关方案的对比4. 小结 1. 写在前面 最近在看相关的Go服务的请求调度的时候,发现在gin中默认提供的中间件中,不含有请求调度相关的逻辑中间件,去github查看了一些服务框架,发…

Linux安装Docker

一、Docker系统版本介绍 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 操作系统的机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相…

机器学习笔记:李宏毅diffusion model

1 概念原理 首先sample 一个都是噪声的vector然后经过denoise network 过滤一些杂质接着继续不断denoise,直到最后出来一张清晰图片 【类似于做雕塑,一开始只是一块石头(噪声很杂的雕塑),慢慢雕刻出想要的花纹】 同一个…

【软件工程】软件测试

软件测试的对象 软件程序文档 测试对象:各个阶段产生的源程序和文档。 软件测试的目的 基于不同的立场,对软件测试的目的存在着两种完全对立的观点。 (1)一种观点是通过测试暴露出软件中所包含的故障和缺陷(从用户的角度)&#xf…

【Unity细节】Unity打包后UI面板消失是怎么回事

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity细节和bug ⭐关于物体的动画碰到其他碰撞器后停止播放的问题⭐ 文章目录 ⭐关于物体的动画碰…

系统架构设计专业技能 · 网络规划与设计(三)【系统架构设计师】

系列文章目录 系统架构设计专业技能 网络规划与设计(三)【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计(四)【系统架构设计师】 系统架构设计高级技能 软件架构设计(一)【系统架构设计师…

学习笔记整理-JS-03-表达式和运算符

[[toc]] 一、表达式和运算符 1. 表达式 表达式种类 算术、关系、逻辑、赋值、综合 二、JS基本表达式 1. 算术运算符 意义运算符加减-乘*除/取余% 加减乘除 加减的符号和数学一致,乘号是*号,除法是/号默认情况,乘除法的优先级高于加法和…

flutter开发实战-实现marquee根据文本长度显示文本跑马灯效果

flutter开发实战-实现marquee文本跑马灯效果 最近开发过程中需要marquee文本跑马灯效果,这里使用到了flutter的插件marquee 效果图如下 一、marquee 1.1 引入marquee 在pubspec.yaml中引入marquee # 跑马灯效果marquee: ^2.2.31.2 marquee使用 marquee使用也是…

C++QT教程3——手册4.11.1自带教程(笔记)——创建一个基于Qt Widget的应用程序

文章目录 创建一个基于Qt Widget的应用程序创建Text Finder项目素材文件 填补缺失的部分设计用户界面完成头文件完成源文件创建资源文件 编译和运行程序 参考文章 创建一个基于Qt Widget的应用程序 本教程介绍如何使用Qt Creator创建一个小型Qt应用程序,名为Text F…

java面试题(16):Mysql一致性视图是啥时候建立的

1 演示错误案例 先给大家来一个错误演示。 我们打开两个会话窗口,默认情况下隔离级别是可重复读,我们来看下: 首先在 A 会话中查看当前 user 表,查看完成后开启事务: 可以看到id3的数据sex是男。 接下来在 B 会话中…

阿里云服务器安装部署Docker使用教程

本文阿里云百科分享如何在云服务ECS实例上,部署并使用Docker。Docker是一款开源的应用容器引擎,具有可移植性、可扩展性、高安全性和可管理性等优势。开发者可将应用程序和依赖项打包到一个可移植的容器中,快速发布到Linux机器上并实现虚拟化…