Redis持久化(RDB AOF)

news2025/1/19 16:25:22

Redis持久化

MySQL的事务,有四个比较核心的特性:

  1. 原子性
  2. 一致性
  3. 持久性(和持久化一样),将数据存储在硬盘上,重启主机之后数据仍然存在
  4. 隔离性

redis是一个内存数据库,把数据存储在内存中,是不持久的,就需要将redis中的数据存储在硬盘上。

redis最明显的优势就是效率高,快。

为了保证速度快,数据肯定还是得在内存中,但是为了持久,数据得在硬盘中,所以redis就是内存和硬盘中都存,这样存储在两个地方的数据都是一样的。

代价是消耗了更多的空间,同样的数据存储了两遍,但是硬盘便宜没有太多的成本。

两边都存储但是实际上具体怎么写入硬盘还有不同的策略可以保证整体的效率足够高。

  • 插入数据的时候,内存硬盘都写
  • 查询数据的时候,直接从内存中读取
  • 硬盘中的数据只在redis重启的时候用来恢复内存中的数据

Redis持久化实现策略

Redis 提供了两种持久化⽅式:RDBAOF,即可以⽤两种策略将内存的数据保存到硬盘中 .

RDB => redis DataBase

定期把Redis内存中的所有数据都存入到硬盘中,生成一个快照。

定期的实现方式有两种:

  1. 手动触发:

    程序员通过Redis客户端执行特定的命令来触发快照生成。

    • save:执行save的时候Redis就会全力以赴的执行快照生成操作,此时就会阻塞Redis的其他客户端的命令,类似于keys*的后果,Redis系统服务可能就挂了。

    • bgsave:background不会影响Redis服务器处理其他客户端的请求和命令。

      • Redis怎么做到的这种?并发编程的场景,多线程是一种方式,还可以使用其他方式,多进程的方式来完成的。

      • bgsave执行流程

        Redis服务器就是父进程,

        1. 判定当前是否已经存在其他正在进行的子进程,比如现在已经有一个子进程 执行bgsave,此时就把当前的bgsave返回。

        2. 如果没有其他的工作子进程,就通过fork这样的系统调用创建出一个子进程,子进程会复制一份父进程的数据包括进程控制块,程序地址空间,文件描述符表等。

          本来Redis-Server中存储了若干变量,保存了键值对数据。因为fork的进行,子进程的虚拟内存中也会得到和刚才父进程一样的变量数据。

          安排子进程去执行持久化操作,也就相当于把父进程本体给持久化了。

          fork在进行内存拷贝的时候,不是简单的复制一份,而是执行写时拷贝的机制。如果父子进行的内存数据一样,此时就不会触发真正的拷贝动作,两个角色共用一份数据。但是当某一方要进行修改时就会触发真正的物理内存上的数据拷贝。

          在这个场景中,绝大部分内存数据是不需要改变的,整体来说这个过程执行的还挺快的,短时间内父进程中不会存在大批的内存数据变化,写时拷贝也不会触发很多次。

        3. 子进程负责进行写文件,生成快照的过程。父进程继续接收客户端的请求,继续正常的提供服务。

        4. 子进程完成整体的持久化过程之后就会通知父进程,父进程更新统计信息之后子进程就可以销毁了。

      image-20240529121040290

      • RDB文件是存放在Redis的工作目录的,也是在Redis配置文件中进行配置的。

        • RDB机制生成的镜像文件是二进制文件,把内存中的数据以压缩的形式保存到这个二进制文件中,消耗一定的CPU资源但是能节省存储空间

        • 后续Redis服务器重新启动,就会加载这个rdb文件,如果发现格式错误就可能会加载失败,所以别轻易改。

        • Redis提供了rdb文件检测工具:redis-check-rdb*

        • 当执行生成rdb镜像操作的时候,就会把要生成的快照数据先保存到一个临时文件中,当快照生成完毕之后再删除原来的rdb文件,把新创造的临时的rdb文件名改为刚才的dump.rdb文件。

        • rdb文件中的数据不是这边插入新的键值对之后就会立即更新,触发时机是包含手动触发(save,bgsave),和自动触发(在配置文件中进行设置).所以在一段时间以内就可能存在数据上的偏差,那么如果在这一小段时间内服务器挂了,这些数据就丢了。

          sudo vim etc/redis/redis.conf

        image-20240530163615398

        • 由上图可知比如两次生成rdb之间的间隔最少得是60s.12:00:00生成了rdb(硬盘上的快照数据和内存中一致)12:00:01开始Redis接收到大量的key的变化请求,12:01:00生成下一个快照文件,两个快照中间的数据就丢了.
    • 手动执行bgsave之后就会在/var/lib/redis目录下生成dump.db文件,当重启Redis服务器之后,就会加载这个文件中保存的内容,实现持久化的操作.

      在这里插入图片描述

    • Redis生成快照的操作,不仅仅是手动执行命令bgsave才会触发,也可以自动触发.

      • 通过配置文件中的save执行M时间内修改N次…
      • 通过shutdown命令(Redis里面的命令)关闭Redis服务器也会触发.(属于正常关闭 service命令关闭)
      • Redis进行主从复制的时候,主节点也会自动生成RDB快照,然后把rdb快照文件内容传输给从节点.
      • 如果使用异常重启,比如使用kill命令直接终止Redis服务器进程,此时就不会保存.
    • bgsave操作流程是创建子进程,子进程完成持久化操作.持久化会把数据写入到新的文件中,然后使用新的文件替换旧的文件.可以使用stat命令,查看文件的inode编号.如果发现发生了替换,说明已经是不同的文件了.

      image-20240624142210902

    • 如果是save命令,就不会触发子进程和文件替换逻辑,就直接在当前进程中往刚才的同一个文件中写入数据了.

  2. 自动触发:

    Redis配置文件中设置一下save A && B,让Redis每隔多长时间,每产生多少次修改就触发。

    • 执行flushall也会清空rdb文件.

    修改配置文件之后重启服务器之后才能生效.

    save ""关闭自动生成快照.

    • 如果把RDB文件故意搞坏会发生什么呢?

    注意: 使用kill进程的方式重新启动Redis服务器当手动的把rdb文件内容搞坏时,这样才能验证实验效果.

    重启之后将搞坏的rdb文件加载到内存中,貌似是没有收到影响,能够正确获取到数据,具体Redis会咋样,具体取决于文件坏的地方在哪里.如果确实改错地方了,可能Redis服务器都启动不了了,redis日志中会有记录.

    RDB日志记录

RDB优缺点

RDB 是⼀个紧凑压缩的⼆进制⽂件,代表 Redis 在某个时间点上的数据快照。⾮常适⽤于备份,全量复制等场景。⽐如每 6 ⼩时执⾏ bgsave 备份,并把 RDB ⽂件复制到远程机器或者⽂件系统中(如 hdfs)⽤于灾备。

Redis 加载RDB恢复数据远远快于 AOF 的⽅式。 RDB是使用二进制的方式,所以比文本解析的方式更快.

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

RDB ⽂件使⽤特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有⻛险.

AOF=> Append Only File

实时备份数据

类似于MySQL中的binlog存储的是用户的每个操作,都记录到文件中.当Redis重新启动的时候就会读取这个aof文件中的内容,用来回复数据.

  • 当开启aof的时候RDB就不再生效了,启动的时候就不再读取.

  • 默认是关闭的,需要在配置文件中开启,修改配置文件后要重新启动Redis服务器.

image-20240625175957664

  • aof是一个文本文件,每次进行的操作,都会被记录在文本文件中.通过一些特殊符号作为分隔符,来对命令的细节做出区分.

image-20240625180242366

image-20240625180644873

aof性能问题

redis虽然是单线程,但是速度很快,原因是只是操作内存,引入aof之后又要写硬盘.实际上并没有影响到Redis处理请求的速度.

  1. aof机制并没直接让工作线程写入硬盘,而是先写入一个内存中的缓冲区积累一些之后再统一写入硬盘,大大减少了写入硬盘的次数.

    • 写硬盘的效率和每一次写入的数据多少关系不大,主要是写入硬盘的次数影响最大.

    • 如果在写入缓冲区的时候进程挂了,缓冲区的数据就丢了.

      Redis给出选项,让程序员根据实际情况来取舍,缓冲区的刷新策略.

      • 刷新频率越高,性能影响越大,数据可靠性越高.

      • 刷新频率越低,性能影响越小,数据可靠性越低.

      image-20240625182132115

      查看配置文件中的默认缓冲区同步策略就是everysec.
      image-20240625182353728

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

image-20240625181013947

aof重写

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

AOF文件中一些内容是冗余的,比如一下举例操作:

lpush key 111
lpush key 222
lpush key 333
# 整合为一条命令即可
lpush key 111 222 333

set key 111
set key 222
set key 333
# 只关注最后一条更新命令
set key 333

set key 111
del key
set key 222
del key 
# 啥都不做就可以

因此Redis存在一个机制,能够针对aof文件进行整理操作,能够剔除其中的冗余操作,并且合并一些操作,达到给aof文件瘦身的效果=>aof的重写机制.

AOF 重写过程可以手动触发和自动触发:

  • 手动触发:调用 bgrewriteaof命令。

  • 自动触发:根据 auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage 参数确定自动触发时机。

    • auto-aof-rewrite-min-size:表示触发重写时 AOF 的最小文件大小,默认为 64MB

    • auto-aof-rewrite-percentage:代表当前 AOF 占用大小相比较上次重写时增加的比例。

aof重写流程

在这里插入图片描述

  1. 执行 AOF 重写请求。
    如果当前进程正在执行AOF重写,请求不执行。如果当前进程正在执行bgsave 操作,重写命令延迟到 bgsave 完成之后再执行。
  2. 父进程执行 fork 创建子进程。
  3. 重写
  • 主进程 fork 之后,继续响应其他命令。所有修改操作写入 AOF 缓冲区并根据 appendfsync策略同步到硬盘,保证 AOF文件机制正确。
  • 子进程只有 fork之前的所有内存信息,父进程中需要将 fork之后这段时间的修改操作写入
    AOF 重写缓冲区中,aof-rewrite-buf.
  1. 子进程根据内存快照,将命令合并到新的 AOF 文件中。
  • 重写的时候并不关注aof原有文件原来都有啥,只是关心内存中最终的数据状态,就已经相当于把aof文件结果整理后的模样了.
  • aof重写是按照aof要求的文本格式来生成的.
  1. 子进程完成重写
  • 新文件写入后,子进程发送信号给父进程,告知完成瘦身操作了。
  • 父进程把 AOF重写缓冲区内临时保存的命令追加到新 AOF文件中。
  • 用新 AOF 文件替换老AOF文件。
  • 如果在执行bgrewriteaof的时候,当前Redis重写流程正在进行,此时不会再执行重写操作,直接返回.
  • 如果在执行bgrewriteaof的时候,发现当前Redis正在进行RDB快照,此时会等待快照生成结束之后再进行重写操作.
  • RDB理念就是定期备份,并不是实时备份,没有好坏之分,只有使用场景的不同.

  • 父进程fork完毕之后,子进程已经再写新的aof文件了,父进程还有必要写这个即将消亡的文件吗? 有,如果在重写的过程中服务器挂了,这个即将消亡的文件算是一个备份.

  • aof本来是按照文本的方式写入文件,但是文本的方式写文件,后续加载的成本还是比较高的,Redis就引入了混合持久化的方式,结合了RDBaof的特点,按照aof的方式,每一个请求操作都记录在文件中,在出发aof重写之后,就会把当前内存的状态按照rdb的二进制格式写入到新的aof文件中,后续再进行的操作,仍然是按照aof文本的方式追加到文件的后面.

    aof-use-rdb preamble yesredis.conf中进行配置,打开混合持久化选项.

    image-20240628152034554

image-20240628151909356

image-20240628151951520

当同时存在rdbaof机制,以aof为主.

image-20240628152208586

总结

  1. Redis 提供了两种持久化方案:RDBAOF
  2. RDB 视为内存的快照,产生的内容更为紧凑,占用空间较小,恢复时速度更快。但产生 RDB的开
    销较大,不适合进行实时持久化,一般用于冷备和主从复制。
  3. AOF 视为对修改命令保存,在恢复时需要重放命令。并且有重写机制来定期压缩 AOF 文件。
  4. RDBAOF 都使用 fork 创建子进程,利用 Linux 子进程拥有父进程内存快照的特点进行持久化,
    尽可能不影响主进程继续处理后续命令。
    提供了两种持久化方案:RDBAOF`。
  5. RDB 视为内存的快照,产生的内容更为紧凑,占用空间较小,恢复时速度更快。但产生 RDB的开
    销较大,不适合进行实时持久化,一般用于冷备和主从复制。
  6. AOF 视为对修改命令保存,在恢复时需要重放命令。并且有重写机制来定期压缩 AOF 文件。
  7. RDBAOF 都使用 fork 创建子进程,利用 Linux 子进程拥有父进程内存快照的特点进行持久化,
    尽可能不影响主进程继续处理后续命令。

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

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

相关文章

基于SpringBoot的超市进销存系统

你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:SpringBoot框架 工具:MyEclipse、Tomcat 系统展示 首页 首页界面图 个人中心 个人中心…

Kafka~特殊技术细节设计:分区机制、重平衡机制、Leader选举机制、高水位HW机制

分区机制 Kafka 的分区机制是其实现高吞吐和可扩展性的重要特性之一。 Kafka 中的数据具有三层结构,即主题(topic)-> 分区(partition)-> 消息(message)。一个 Kafka 主题可以包含多个分…

【OpenREALM学习笔记:13】pose_estimation.cpp和pose_estimation.h

UML Class Diagram 图中红色框为头文件中所涉及到的函数、变量和结构体 核心函数 PoseEstimation::process() 其核心作用为执行位姿估计的处理流程,并返回是否在此循环中进行了任何处理。 在这个函数中判断并完成地理坐标的初始化或这地理坐标的更新。 这里需要…

【算法专题--栈】用队列实现栈 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐两个队列实现栈 🥝解题思路 🍍案例图解 ⭐用一个队列实现栈 🍇解题思路 🍍案例图解 四、总结与提炼 五、共勉 一、前言 用队列实现栈 这道题,可以说是--栈…

springcloud第4季 分布式事务seata实现AT模式案例2【经典案例】

一 seata案例 1.1 背景说明 本案例使用seata的at模式,模拟分布式事务场景:【下订单,减库存,扣余额,改状态】 AT模式原理:是2pc方案的演变, 一阶段:业务数据和回滚日志记录在同一…

【MotionCap】conda 链接缺失的cuda库

conda 安装的环境不知道为啥python 环境里的 一些cuda库是空的要自己链接过去。ln 前面是已有的,后面是要新创建的 ln -s <path to the file/folder to be linked> cuda 有安装 libcublas 已经在cuda中 (base) zhangbin@ubuntu-server:~/miniconda3/envs/ai-mocap/lib/…

转让无区域商业管理公司基本流程和要求

无区域公司转让的条件和要求取决于您的业务需求和目标。我们的专业团队将与您合作&#xff0c;深入了解您的公司背景、行业情况和发展计划&#xff0c;为您量身定制适合您的转让方案。无论是公司规模、经营期限、资产状况还是法律形式&#xff0c;我们都将综合考虑确保达到您的…

学习C语言第一步:300行代码实现输出“Hello World“

学习所有语言的第一步几乎都是在控制台输出"Hello World",C语言也是如此&#xff0c;C语言支持结构化编程、词汇范围和递归等特性&#xff0c;C语言编写的代码在稍作修改或无需修改的情况下可以在多种不同的操作系统和平台上编译和运行&#xff0c;同时运行速度极快。…

如何为数据库中的位图添加动态水印

许多数据库存储了以blob或文件形式保存的位图&#xff0c;其中包括照片、文档扫描、医学图像等。当这些位图被各种数据库客户端和应用程序检索时&#xff0c;为了日后的识别和追踪&#xff0c;有时需要在检索时为它们添加唯一的水印。在某些情况下&#xff0c;人们甚至希望这些…

【数组】- 螺旋矩阵 II

1. 对应力扣题目连接 螺旋矩阵 II 题目简述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。如图&#xff1a; 2. 实现案例代码 public class SpiralMatrix {public static…

网页搜索如何优化效果最好?

可以使用长尾关键词策略&#xff0c;长尾关键词策略是指在SEO优化中&#xff0c;除了使用常规的短关键词外&#xff0c;还深入挖掘和使用那些更长、更具体的关键词。虽然这些关键词的搜索量较低&#xff0c;但竞争也较少&#xff0c;且更具针对性&#xff0c;因此往往能带来更高…

我的世界服务器-高版本服务器-MC服务器-生存服务器-RPG服务器-幻世星辰

生存为主&#xff0c;RPG乐趣为辅&#xff0c;重视每位玩家的建议&#xff0c;一起打造心目中的服务器&#xff0c;与小伙伴一起探险我的世界&#xff01; 服务器版本: 1.18.2 ~ 1.20.4 Q群&#xff1a; 338238381 服务器官网: 星辰毛毛雨-Minecraft高版本生存服务器我的世界…

PMBOK® 第六版 结束项目或阶段

目录 读后感—PMBOK第六版 目录 不论是阶段的收尾还是项目整体的收尾&#xff0c;都应是令人振奋的事。然而&#xff0c;在实际生活中&#xff0c;收尾工作却相当艰难。会遭遇负责人调离、换任&#xff0c;导致不再需要已购产品&#xff1b;项目收尾时对照招标文件或合同&…

[AIGC] 深入了解标准与异常重定向输出

在操作系统和编程环境下&#xff0c;有时我们需要更加精细地控制程序的输入或输出过程&#xff0c;这就涉及到了标准输入输出流&#xff0c;以及重定向的概念。接下来&#xff0c;我们将详细介绍标准输出、标准错误输出&#xff0c;以及如何进行输出重定向。 文章目录 1. 标准输…

企业im(即时通讯)作为安全专属的移动数字化平台的重要工具

企业IM即时通讯作为安全专属的移动数字化平台的重要工具&#xff0c;正在越来越多的企业中发挥着重要的作用。随着移动技术和数字化转型的发展&#xff0c;企业对于安全、高效的内部沟通和协作工具的需求也越来越迫切。本文将探讨企业IM即时通讯作为安全专属的移动数字化平台的…

坏越的小世界的一些修改调整

留言区感觉不够高大上&#xff0c;功能也比较简单。我想了想还是仿照小红书设计一个。 先写个静态 这边想了想是将留言和评论各放一个表和首次加载的放在一个表好。想了想还是选择了后者 不过在sql上这样可能会很麻烦&#xff0c;还是建议分表&#xff0c;看下布局 每次展开会…

QT加载安装外围依赖库的翻译文件后翻译失败的现象分析:依赖库以饿汉式的形式暴露单例接口导致该现象的产生

1、前提说明 VS2019 QtClassLibaryDll是动态库,QtWidgetsApplication4是应用程序。 首先明确:动态库以饿汉式的形式进行单例接口暴露; 然后,应用程序加载动态库的翻译文件并进行全局安装; // ...QTranslator* trans = new QTranslator();//qDebug() << trans->…

支付宝支付之收款码支付

文章目录 收款码支付接入流程安全设计系统交互流程交易状态统一收单交易支付接口请求参数测试结果查询支付撤销支付退款支付退款结果退款说明 收款码支付 继&#xff1a;支付宝支付之入门支付 接入流程 安全设计 支付宝为了保证交易安全采取了一系列安全手段以保证交易安全。…

路由器的ip地址与网关的区别是什么

在网络世界中&#xff0c;路由器扮演着至关重要的角色&#xff0c;它负责数据的传输和网络的互联。而在路由器的设置中&#xff0c;有两个常见的概念&#xff1a;IP地址和网关。那么&#xff0c;路由器的IP地址与网关的区别是什么&#xff1f;下面与虎观代理小二一起了解一下吧…

德国威步的技术演进之路(上):从软件保护到用户体验提升

德国威步自1989年成立以来一直专注于数字安全技术的研究和发展&#xff0c;在软件保护和数字授权领域树立了行业标杆&#xff0c;并在云端许可管理和物联网安全技术方面不断创新。德国威步的成就彰显了其对安全、创新和可持续发展的坚定追求。 德国威步将“完美保护、完美授权…