Redis——持久化

news2024/11/26 3:48:44

文章目录

  • Redis持久化
    • Redis的两种持久化的策略
      • 定期备份:RDB
        • 触发机制
        • rdb的触发时机:
        • 手动执行save&bgsave保存测试
        • 不手动执行bgsave测试
        • bgsave操作流程测试
        • 通过配置,自动生成rdb快照
        • RDB的优缺点
      • 实时备份:AOF
        • AOF是否会影响到redis的性能
        • AOF的重写机制
          • 重写触发方式
          • AOF重写的流程
      • 总结

Redis持久化

在这之前要提及到Mysql的事务的四个比较核心的特性

原子性 一致性 持久性 隔离性

这里mysql的持久性就是把数据存储在硬盘上,而redis数据是存在内存里的,要想做到持久,就需要让redis把数据存储到硬盘上

Redis相比于Mysql这样的关系型数据库,最明显的特点/优势就是 快,所以为了保证速度快,数据肯定还是得在内存中,但是为了持久,数据还得办法存储在硬盘上

Redis决定 内存中也存数据,硬盘上也存数据,这样的两份数据,理论上是完全相同的

  • 当要插入一个新的数据的时候,就需要把这个数据同时写入到内存和硬盘(说是两边都写,但是实际上具体怎么写硬盘还有不同的策略,可以保证整体的效率还是足够的高)
  • 当查询某个数据的时候,直接从内存读取
  • 硬盘的数据只是在redsi重启的时候,用来恢复内存中的数据
  • 代价就是消耗了更多的空间,同一份数据,存储了两遍(但是毕竟硬盘比较便宜,这样的开销并不会带来太多的成本)

Redis的两种持久化的策略

  1. RDB => Redis DataBase 定期备份:每隔一段时间,进行一次备份
  2. AOF => Append Only File 实时备份:只要有数据变动,立即备份

定期备份:RDB

RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发自动触发

触发机制
  • 手动触发:通过redis客户端执行特定的命令,来执行快照生成 (手动触发分别对应 save 和 bgsave 命令)

• save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例造成长时间阻塞,基本不采用
• bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,⼀般时间很短。

Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave 的方式。

在这里插入图片描述

  1. 执行 bgsave 命令,Redis 父进程判断当前进是否存在其他正在执行的子进程,如 RDB/AOF 子进
    程,如果存在 bgsave 命令直接返回。
  2. 父进程执行 fork 创建子进程,fork 过程中父进程会阻塞,通过 info stats 命令查看latest_fork_usec 选项,可以获取最近⼀次 fork 操作的耗时,单位为微秒。
  3. 父进程 fork 完成后,bgsave 命令返回 “Background saving started” 信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后⼀次生成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给父进程表⽰完成,父进程更新统计信息。
  • 自动触发:在Redis配置文件中,设置一下,让Redis每隔多长时间/每产生多少次修改 就触发

Redis生成的RDB文件,是存放在redis的工作目录中的,也是在redis的配置文件中进行设置的

在这里插入图片描述

这里的dump.rdb文件,就是rdb机制生成的镜像文件,redis服务器默认就是开启了rdb的,这个镜像文件,是一个二进制的文件,把内存中的数据,以压缩的形式,保存到这个二进制文件中

后续redis服务器重新启动,就会尝试加载这个rdb文件,如果发现格式有错误,就可能会加载数据失败

rdb文件,虽然我们没有主动去动他,但是也有可能会出现一些意外问题,一旦通过一些操作(比如网络传输)引起这个文件被破坏,此时redis服务器就无法启动

  • redis提供了rdb文件的检查工具 redis-check-rdb

查看一下RDB文件里面是什么内容

在这里插入图片描述

里面都是二进制内容,当我们对redis文件中的数据进行增删查改时,这里的RDB文件并不会立即更新

rdb的触发时机:
  1. 手动(save,bgsave)
  2. 自动(配置文件中,进行设置)

在这里插入图片描述

在这里插入图片描述

save //seconds之内至少存在changes次key的修改

虽然此处的这些数值,都可以自由修改配置,但是此处修改上述数据的时候,要有一个基本规则

生成一次rdb快照,这个成本是一个比较高的成本,不能让这个操作执行的太频繁

正因为rdb不能生成的太频繁,这就导致,快照里的数据,和当前实时的数据情况可能会存在偏差

save 60 10000 (两次生成rdb之间的间隔,至少得是60s)

假设当前

12:00:00生成了rdb(硬盘上的快照数据和内存中一致)

12:00:01开始,redis收到了大量的key的变化请求

12:01:00生成下一个快照文件

在上述过程之间,redis服务器挂了,此时就会导致,12:00:00之后的这些数据,就丢了(数新的据只是在内存里,还没存到rdb)

手动执行save&bgsave保存测试

由于这里执行的数据比较少,所以瞬间就完成了,立即查看应该是有结果的,如果数据比较多,执行bgsave就需要消耗一定的时间,立即查看不一定就是生成完毕了

在这里插入图片描述

保存后查看rdb文件可以看到已经发生了修改

在这里插入图片描述

持久化验证,可以看到,通过上述操作,redis服务器在重新启动的时候,加载了rdb文件的内容,恢复了内存中之前的状态

在这里插入图片描述

redis生成快照操作,不仅仅是手动执行命令才触发,也可以自动触发~

  1. 通过配置文件中save执行M时间内,修改N次…
  2. 通过shotdown命令(redis里的一个命令)关闭redis服务器,也会触发
  3. redis进行主从复制的时候,主节点也会自动生成rdb快照,然后把rdb快照文件内容传输给从节点
不手动执行bgsave测试

插入新的key,不手动执行bgsave,重新启动redis服务器

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

bgsave操作流程测试

bgsave操作流程是创建子进程,子进程完成持久化操作,持久化会把数据写入到新的文件中,然后使用新的文件替换旧的文件

而子进程完成持久化的速度太快了(数据少),难以观察到子进程,但是我们可以通过文件的inode来验证bgsave操作流程

在这里插入图片描述

在redis客户端执行bgsave后

在这里插入图片描述

可以看到Inode从18685044变为了18685080

通过配置,自动生成rdb快照

这里执行flashall也会自动生成rdb快照

在这里插入图片描述

将时间设置为60秒 设置两次保存rdb

在这里插入图片描述

在这里插入图片描述

如果rdb文件故意改坏了,会怎样

如果改的是结尾的位置,基本没什么影响,如果改的hi中间的位置,那么redis服务器就会挂掉

  • redis提供了rdb文件的检查工具,可以先通过检查工具,检查一下rdb文件格式是否符合要求

在这里插入图片描述

运行的时候,加入rdb文件作为命令行参数,此时就是以检查工具的方式来运行,不会真的启动redis服务器

redis-check-rdb dump.rdb

RDB的优缺点
  • RDB 是⼀个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每 6 小时执行 bgsave 备份,并把 RDB 文件复制到远程机器或者文件系统中 (如 hdfs)用于灾备。

  • Redis 加载 RDB 恢复数据远远快于 AOF 的方式。

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

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

实时备份:AOF

Append Only File

类似于mysql的binlog,会把用户的每个操作,都记录到文件中,当redis重新启动的时候,就会读取这个aof文件中的内容,用来恢复数据

在这里插入图片描述

将这个appendonly的属性设置为 yes后,重启redis服务器,这里我执行两次set命令后查看 /var/lib/redis目录下的文件,发现多了一个文件appendonly.aof

在这里插入图片描述

由文件内容可以看到,AOF是一个文本文件,每次进行的操作都会被录到文本文件中,通过一些特殊的符号作为分隔符,来对命令的细节进行区分

AOF是否会影响到redis的性能

redis虽然是一个单线程的服务器,但是速度很快,引入AOF后,又要写内存,又要写硬盘,还能和之前一样快了吗?

实际上,是没有影响的

  1. AOF机制并非是直接让工作线程把数据直接写入硬盘,而是先写入一个内存的缓冲区,积累一波后,再统一写入硬盘(假设由100个请求,100个请求一次写入硬盘,比分100次写入一个请求要快得多,写硬盘的时候,写入硬盘的数据的多少,对于性能影响没有很大,但是写入硬盘的次数则影响很大)

在这里插入图片描述

  1. 硬盘上读写数据,顺序读写的速度是比较快的(还是比内存要慢得多)随机访问则速度是比较慢的,而AOF是每次把新的操作写到原有文件的末尾,属于 顺序写入

如果把数据写入缓冲区里,本质还是在内存中,万一这个时候,进程突然挂了,或者主机掉电了,咋办?是不是缓冲区中的数据就丢了?? 答案是的,缓冲区没有来得及写入硬盘的数据会丢的

redis给出了一些选项,让程序猿,根据实际情况决定怎么取舍,缓冲区的刷新策略

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

刷新频率越低,性能影响就越小,数据的可靠性就越低~~

可配置值说明取舍情况
always命令写入aof_buf 后调用 fsync 同步,完成后返回频率最高,数据可靠性最高,性能最低
everysec命令写入aof_buf 后只执行 write 操作,不进行 fsync。每秒由同步线程进行 fsync。频率低一些,数据可靠性也会降低,性能会提高
no命令写入 aof_buf 后只执行 write 操作,由 OS 控制 fsync 频率。频率最低,数据可靠性也是最低的,性能是最高的

在这里插入图片描述

通过配置文件可以看到redis默认是everysec策略

AOF的重写机制

AOF文件持续增长,体积越来越大,会影响到redis下次启动的启动时间,redis启动的时候要读取aof文件的内容

redis存在一个机制,能够对aof文件进行整理操作,这个整理就是能够提出其中的冗余操作,并且合并一些操作,达到给aof文件瘦身这样的效果,例如lpush 111 ,lpush 222 合并为 lpush 111 222

重写触发方式
  • 手动触发:调用bgrewriteaof命令
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
    • auto-aof-rewrite-min-size:表示触发重写时AOF的最小文件大小,默认为64MB
    • auto-aof-rewrite-percentage:代表当前AOF占用大小相比较上次重写时增加的比例
AOF重写的流程

创建子进程fork,父进程仍然负责接收请求,子进程负责针对aof文件进行重写

注意: 重写的时候,不关心aof文件中原来都有啥,只是关心内存中的最终的数据状态!

子进程只需要把内存中当前的数据,获取出来,以AOF的格式写入到一个新的AOF文件中

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

在这里插入图片描述

在创建子进程的一瞬间,子进程就继承了当前父进程的内存状态,因此子进程里的内存数据是父进程fork之前的状态,fork之后,新来的请求,对内存造成的修改,是子进程不知道的

此时父进程这里又准备额一个aof_rewrite_buf缓冲区,专门放fork之后收到的数据,子进程这边,把aof数据写完之后,会通过信号通知一下父进程,父进程再把aof_rewrite_buf缓冲区中的内容也谢入到新AOF文件里

就可以用新的AOF文件代替旧的AOF文件了

如果,在执行bgrewriteaof的时候,当前redis已经正在进行aof重写了,会咋样呢?? ————此时不会再次执行aof重写,直接就返回了

如果,在执行bgrewriteaof的时候,当前redis已经正在进行生成rdb文件快照,会咋样呢?? ——此时aof重写操作就会等待,等待rdb快照生成完毕之后,再进行执行aof重写

rdb对于fork之后的新数据,就置之不理了,aof则对于fork之后的新数据,采取了aof_rewrite_buf缓冲区的方式来处理

父进程fork完毕之后,就已经让子进程写心得aof文件了,并且随着时间的推移,子进程很快就写完了新的文件 ,要让新的aof文件代替旧的,父进程此时还在继续写这个即将消亡的旧的aof文件是否还有意义??

这里就要考虑到一种极端的情况

假设重写过程中,重写了一半,服务器挂了,子进程内存的数据就会丢失,新的aof文件内容还不完整,所以如果父进程不坚持写旧的aof文件,重启就没法保证数据的完整性

在这里插入图片描述

打开aof文件可以看到所有的操作都被记录了下来

在这里插入图片描述

查看一下执行bgrewriteaof之前的aof文件信息

在这里插入图片描述

执行一下bgrewriteaof再查看aof文件信息

在这里插入图片描述

查看aof文件内容会发现已经变了, 并且会变成二进制

在这里插入图片描述

为什么会变成二进制呢?

AOF本来是按照文本的方式来写入文件的,但是文本的写入方式,后续的加载成本是很高的,redis就引入了“混合持久化的方式”,结合了rdb和aof的特点。按照aof的方式每一个请求/操作,都录入文件,在触发aof重写之后,就会把当前内存的状态按照rdb的二进制格式写入到新的aof文件中,后续再进行操作,仍然是按照aof文本的方式追加到文件后面的

在这里插入图片描述

在配置文件中,可以选择是否开启混合持久化

当redis上同时存在aof文件和rdb快照的时候,此时以谁为主?以aof为主!!rdb直接被忽略了(因为AOF中包含的数据比RDB更全)

在这里插入图片描述

总结

  1. Redis 提供了两种持久化方案:RDB 和 AOF。

  2. RDB 视为内存的快照,产生的内容更为紧凑,占用空间较小,恢复时速度更快。但产生 RDB 的开
    销较⼤,不适合进行实时持久化,⼀般用于冷备和主从复制。

  3. AOF 视为对修改命令保存,在恢复时需要重放命令。并且有重写机制来定期压缩 AOF 文件。

  4. RDB 和 AOF 都使用 fork 创建⼦进程,利用 Linux ⼦进程拥有⽗进程内存快照的特点进行持久化,
    尽可能不影响主进程继续处理后续命令。

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

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

相关文章

去耦电容的“滤波半径”

1、简介 去耦电容的滤波半径通常指的是在电路板上,去耦电容能够对其周围电源线路或信号线路产生有效去耦作用的范围。这个范围是以去耦电容为中心,向周围扩展的一个特定距离。 想象你有一个水桶,里面装满了混浊的水(含有噪声的信…

基于ESP32的厨房计时器

基于ESP32的厨房计时器 一、项目说明二、项目材料三、OLED显示屏四、外壳设计五、外壳打印六、电路和外壳的集成七、编程八、成品展示 一、项目说明 厨房计时器很有用,但现在没有多少人使用实体厨房计时器了。我个人还是喜欢使用它们,因为拥有一个可以按…

CGAL 带约束的Delaunay三角剖分

CGAL 带约束的Delaunay三角剖分 本文使用CGAL进行简单的2D Delaunay 三角剖分,添加内外边界及点作为约束剖分。 Code #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Constrained_Delaunay_triangulation_2.h> #include <…

问题杂录-NVIDIA Bluefield DPU bfb-build编译报错记录与处理办法?(无数坑)

文章目录 背景bfb-build之后直接退出docker.io无法访问报错 ERROR: failed to solve: processkubernotes 下载失败报错mlnx-fw-updater-signed-24.07-0.6.1.1.aarch64: Cannot download报错 No match for argument: bf-release报错 放弃编译anolis&#xff0c;直接编译老版ubun…

RabbitMQ 入门(二)基本结构和消息模型

一、RabbitMQ的基本结构、角色和消息模型 MQ的基本结构&#xff1a; RabbitMQ中的一些角色&#xff1a; - publisher&#xff1a;生产者 - consumer&#xff1a;消费者 - exchange个&#xff1a;交换机&#xff0c;负责消息路由 - queue&#xff1a;队列&#xff0c;存储消息…

初步认识torch自定义算子

此篇为PyTorch 自定义算子&#xff1a;复现CPU和CUDA版的二维卷积的代码详解 这篇是为了展示setup在构建简单的cpp算子的使用 1.环境配置 整体结构如下图所示 pytorch_cpp_helper.hpp中准备了CPU版卷积需要的头文件 pytorch_cuda_helper.hpp和common_cuda_helper.hpp是cuda…

板级支持包构建1

开发板&#xff1a;STM32h743xi 编程软件&#xff1a;Keil 项目&#xff1a;GPIO外设操作&#xff08;彩色LED灯&#xff09; 学习打卡&#xff1a;Day2 学习地址&#xff1a;【野火】STM32 HAL库开发实战指南 教学视频 手把手教学STM32全系列 零基础入门CubeMXHAL库&#xff0…

jQuery——自定义jQuery插件

1、扩展jQuery&#xff08;将$看成对象&#xff09;的工具方法 $.extend&#xff08;object&#xff09; min&#xff08;a&#xff0c;b&#xff09; 返回较小的值 max&#xff08;c&#xff0c;d&#xff09; 返回较大的值 leftTrim&#xff08;&#xff09; 去掉字符串…

9.4 栅格图层符号化山体阴影渲染

9.4 栅格图层符号化山体阴影渲染-CSDN博客 目录 前言 山体阴影渲染 QGis设置为山体阴影 二次开发代码实现山体阴影 总结 前言 介绍栅格图层数据渲染之山体阴影渲染说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 山体阴影渲染 以“3420C_2010_327_…

leetcode二叉树(一)-理论基础

本节主要参考代码随想录&#xff1a;代码随想录 题目分类 二叉树的种类 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树&#xff0c;也可以说深…

产品设计——应用架构

我的理解应用架构是业务架构的落地&#xff0c;微服务架构下平台的应用架构设计&#xff0c;实质是根据业务来明确应用微服务的边界。因此业务不同&#xff0c;应用架构图也不同。但是基本框架应该相差不大。 其划分原则莫过于高内聚、低耦合。这个跟接口设计是一致的。我们总是…

MySQL数据库安装手册

MySQL数据库安装手册 MySQL数据库的下载与安装 在上一小节我们已经简单了解了数据库与一些相关概念 没看上一节的同学戳这里 接下来我们首先需要学会如何下载和安装数据库 1 MySQL数据库的版本 目前MySQL官网为我们提供了两个版本&#xff0c;一个是社区版本&#xff0c;…

<<迷雾>> 第11章 全自动加法计算机(4)--带地址译码器的内存模型 示例电路

地址译码器 info::操作说明 书中没有给出具体的实现电路. 这里根据电路特性采用自定义逻辑实现. 关于 “自定义逻辑”, 可参考此链接的说明: https://book.xiaogd.net/usage-of-circuitjs/circuitjs-custom-logic.html 这里本质上就是利用两个 2-4 译码器分别控制读和写. 注: 在…

Linux进程控制(3)(进程程序替换2 -- 微型shell)

目录 补充 一.引入 二.自助微型shell 1&#xff1a;输出一个命令行 2&#xff1a;获取用户命令字符串 3&#xff1a;命令行字符串的分割 4&#xff1a;先试着执行一下命令 5&#xff1a;关键点&#xff1a;需要在执行命令前检查是否为内建命令 其他&#xff1a; 三&…

JSONAJAX

JSON&&AJAX 一、JSON 1.1 json简介 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式&#xff0c;而且很多语言都提供了对 json 的支持&#xff08;包括 C, C, C#, J…

常用的devops工具集成方法

常用的devops工具集成方法涵盖了软件开发和运维的各个方面&#xff0c;从版本控制到自动化构建、测试、部署和监控。这些工具的有效集成可以帮助团队提高协作效率&#xff0c;减少沟通障碍&#xff0c;实现快速、高质量的软件交付。以下是对这些工具集成方法的具体介绍&#xf…

双核DSP芯片的内存管理

总体框图 总的来说&#xff0c;在这款DSP芯片上&#xff0c;RAM分成了四种不同的类型&#xff1a; 专用RAM: CPU专用的内存&#xff0c;其他主机无法访问。 双核共享RAM: CLA和CPU共享内存&#xff0c;双方都可以对内存地址进行访问 MSGRAM&#xff1a; CLA和CPU之间传递数据的…

【自动驾驶汽车通讯协议】I2C(IIC)总线通讯技术详解

文章目录 0. 前言1. I2C简介2.I2C的工作原理2.1 硬件要求&#xff1a;2.2 半双工通信&#xff1a; 3. 通信时序4. 其他特性4.1 通信速率4.2 抗干扰措施4.3 注意事项 5. 在自动驾驶汽车中的应用5.1 I2C操作模式5.2 I2C的用途 6. 总结 0. 前言 按照国际惯例&#xff0c;首先声明&…

Spring Boot知识管理系统:创新与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

【含开题报告+文档+PPT+源码】基于人脸识别的课堂考勤系统的设计与实现

开题报告 随着科技的不断发展&#xff0c;人脸识别技术已经逐渐渗透到各个领域&#xff0c;包括教育领域。传统的课堂考勤方式通常依赖于学生签到或教师手动记录&#xff0c;这种方式存在着许多不足之处&#xff0c;例如容易出现人为错误、耗费时间和资源等。为了解决这些问题…