2023.1.15 关于 Redis 持久化 RDB 策略详解

目录

Redis 持久化

                Redis 实现持久化的两大策略

RDB 策略

手动触发

                save 命令

                bgsave 命令

                        bgsave 命令执行流程

自动触发

rdb 文件

实例演示一

实例演示二

实例演示三

实例演示四

RDB 策略的优缺点


Redis 持久化

  • 什么是持久化?

回答:

  • 将数据存储在硬盘上——> 持久
  • 将数据存储在内存上 ——> 不持久
  • 所以持久化的判断标准为 重启进程 或 重启主机 后,数据是否存在!

  • Redis 是一个内存数据库,即将数据存储在内存中
  • 但内存中的数据是不持久的,要想能够做到持久,就需要让 Redis 将数据存储到硬盘上
  • Redis 相比于 MySQL 关系型数据库,其最明显的特优势为 效率高、速度快
  • 所以为了保证速度快,Redis 的数据肯定还是得存储在内存中
  • 但是为了持久化,Redis 的数据还得想办法存储在硬盘上
  • 随之 Redis 决定在 内存 中存储数据的同时 硬盘 上也进行数据的存储

通俗理解:

  • 当插入一个新数据时,将该数据同时写入到内存和硬盘
  • 当查询某个数据时,直接从内存读取
  • 硬盘上的数据只是在 Redis 重启的时候,用来恢复内存中的数据的

代价:

  • 消耗了更多的空间,即同一份数据存储了两遍
  • 但是由于硬盘比较便宜,因此这样的开销并不会带来多大的成本

注意点一:

  • 内存上 和 硬盘上 的两份数据,理论上是完全相同的
  • 但实际上可能存在一些小差异,这完全取决于我们如何针对数据进行持久化

注意点二:

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

Redis 实现持久化的两大策略

  • RDB ——> Redis DataBase(定期备份)
  • AOF ——> Append Only File(实时备份)

注意:

  • Redis 服务器配置文件默认开启 RDB(定期备份)

RDB 策略

  • RDB 定期将 Redis 内存中的所有数据都给写入到硬盘中,即生产一个 "快照"

通俗理解:

  • Redis 给当前在内存中存储的所有数据拍个照片,生成一个 rdb 文件,并将其存储在硬盘中
  • 如果后续 Redis 服务器一旦重启了(内存数据就没了),就可以根据刚才的 "快照" 将内存中的数据给恢复回来

  • RDB 定期备份具有两种触发方式,分别为 手动触发、自动触发

手动触发

  • 程序员通过 Redis 客户端执行特定的命令,以此触发 "快照" 生成

save 命令

  • 执行 save 命令时,Redis 会全力以赴的生成 "快照" ,此时就有可能阻塞 Redis 的其他客户端命令

注意:

  • 使用改命令时,可能会导致类似于 keys * 的后果
  • 所以一般不建议使用 save 命令

bgsave 命令

  • bg ——> backgroud(后面)即不会影响 Reids 服务器处理其他客户端的请求和命令

问题:

  • Redis 时如何做到的呢? 是否弄了个多线程来执行该命令? 

回答:

  • 此处 Redis 使用 多进程 的方式来完成的并发编程,从而完成的 bgsave 命令的实现

bgsave 命令执行流程


第一步

  • 判定当前是否已经存在其他正在工作的子进程

  • 比如现在已经有一个子进程正在执行 bgsave,此时将直接把当前的 bgsave 返回


第二步

  • 如果没有其他的工作子进程,就通过 fork 这样的系统调用来创建一个子进程

重点理解:

  • Java 进行并发编程时,主要通过 多线程 的方式
  • fork 是 linux 系统提供的一个创建子进程的 api (系统调用)
  • fork 会直接将当前的进程(父进程)复制一份,作为子进程
  • 复制完成之后,父子进程就变为两个独立进程,即各自执行各自的
  • 此处所说的复制操作 会复制 pcb 虚拟地址空间(内存中的数据)、文件描述符表等
  • 本来 Redis 服务器中有若干变量,即保存了一些键值对数据
  • 随着 fork 的进行,子进程的这个内存里也会存在和刚才父进程中一模一样的变量(键值对数据)
  • 因此子进程 内存中的数据 和 父进程 内存中的数据 相同
  • 接下来便安排子进程去执行 持久化 操作,也就相当于把父进程本体这里的内存数据给持久化了

注意:

  • 正因为 父进程文件描述符表 也被 子进程 给复制了
  • 所以当父进程打开了一个文件 且  fork 了之后,子进程也是可以同样使用这个文件的
  • 因此也就导致了子进程持久化写入的那个文件和父进程本来要写的文件是同一个

问题:

  • 如果当前 Redis 服务器中存储的数据特别多,内存消耗特别大(比如 100G)
  • 此时进行上述的复制操作是否会有很大的内存开销?

回答:

  • 此处的性能开销其实挺小的
  • fork 在进行内存拷贝时,不是无脑的直接将所有数据均拷贝一遍,而是以 写时拷贝 的机制来完成的

  • 如果子进程里的这个内存数据和父进程的内存数据完全一致,此时就不会触发真正的拷贝动作,而是子父进程共用同一份内存数据
  • 但是子父进程的内存空间各自独立
  • 一旦某个内存数据做了修改,此时便会立即触发真正的 物理内存 上的数据拷贝

小总结:

  • 在进行执行 bgsave 命令时,绝大部分的内存数据是不需要改变的
  • 整体来说这个过程执行还挺快的
  • 因为短时间内,父进程中不会有大批的内存数据的变化
  • 因此子进程 写时拷贝 并不会触发很多次,也就保证了整体的拷贝时间是可控的、高效的

第三步

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

第四步

  • 子进程完成整体的持久化过程之后,就会通知父进程,干完了,父进程就会更新一些统计信息
  • 执行至此 子进程 便可以结束并销毁了!

 自动触发

自动触发 Redis 生成快照的操作有多种方式:

  1. 通过刚才配置文件中  save 执行 M 时间内,修改 N 次
  2. 通过 shutdown 命令(redis 里的一个命令)关闭 redis 服务器,也会触发(正常关闭)
  3. 在 Redis 进行主从复制时,主节点也会自动生成 rdb 快照,然后将 rdb 快照文件内容传输给从节点

注意:

  • 但在实际开发中,更害怕的是出现异常情况!

  • Rdis 的配置文件中关于方式一如下图所示

方式一的触发条件:(默认值)

  • 900 秒内 至少 1 次 key 的修改
  • 300 秒内 至少 10 次 key 的修改
  • 60 秒内 至少 10000 次 key 的修改

注意:

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

原则:

  • 生成一次 rdb "快照",是高成本的操作,所以不能让该操作执行的太频繁!
  • 在默认配置中,生成两次 rdb "快照" 之间的间隔最少也为 60秒

小总结:

  • 正因为 rdb "快照"生成的不能太频繁
  • 因此也就导致 "快照" 里的数据和当前实时的数据情况可能存在一定偏差

实例理解

rdb 文件

  • Redis 生成的 rdb 文件存放在 Redis 的工作目录中 Redis 配置文件可自行设置)


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

注意点一:

  • Redis 服务器重新启动,就会尝试加载这个 rdb 文件
  • 如果发现格式错误,就可能会加载数据失败!
  • rdb 文件,在我们不主动修改它的前提下,也可能会存在一些意外情况
  • 即 一旦通过一些操作(比如网络传输)引起 rdb 文件被破坏,此时 Redis 服务器就无法启动

ps:

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

注意点二:

  • rdb 持久化操作可触发多次
  • 当执行生成 rdb 镜像操作的时候
  • 此时就会把要生成的快照数据,先保存到一个临时文件中
  • 当这个快照生成完毕之后,再删除之前的 rdb 文件,把新生成的 rdb 文件名字改成刚才的 dump.rdb
  • 因为从始至终,rdb 文件有且仅有一个

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

注意:

  • 因为 持久化速度太快了(数据少),我们难以观察到 子进程
  • 但是 使用新文件替换旧文件 这个是可以观察到的

实例理解

  • 使用 linux 的 stat 命令,查看文件的 inode 编号


补充点一:Linux 文件系统

  • 文件系统典型的组织方式(ext4)主要把整个文件系统分成了三个大的部分:
  1. 超级块(放的是一些管理信息)
  2. inode 区(存放 inode 节点 每个文件都会分配一个 inode 数据结构,包含了文件的各种元数据)
  3. block 区(存放文件的数据内容)

补充点二:

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

实例演示一

  • 根据该实例演示,我们来仔细观察新 rdb 文件的生成

1、Redis 未设置 任何键值对的 dump.rdb 文件


2、向 Redis 设置 3个键值对


3、再次打开 dump.rdb 文件,此时并未发生任何变化

注意:

  • rdb 文件中的数据,不是你这边插入了数据,就会立即更新的

RDB 机制的触发时机:

  • 手动触发(save、bgsave)
  • 自动触发

原因:

  • 正因为刚才插入 3个键值对,没有运行手动触发的命令,也达不到自动触发的条件
  • 因此 dump.rdb 文件并未发生改变 

4、此时我们手动执行 bgsave 命令触发一次生成快照

  • 由于此处的数据比较少,执行 bgsave 命令后 一瞬间便完成了

5、立即查看应该就是有结果的

  • 此处我们可以看到 dump.rdb 中已经发生了改变!

注意:

  • 如果 Redis 中的数据多,执行 bgsave 命令就可能需要消耗一定的时间
  • 立即查看不一定就是生成完毕了

6、将现在正在运行的 Redis 服务器重启,看是否能恢复内存之前的状态

  • 由上图可知,Redis 服务器在重新启动时,加载了 rdb 文件的内容,恢复了内存之前的状态

7、向 Redis 中设置新的键值对,但不手动执行 bgsave 命令直接重启 Redis 服务器

  • 刚才没有执行 bgsave 命令,但是这个 key4 居然在重启之后仍然存在!
  • 自动触发 ——> 方式二

8、打开并查看 dump.db 文件

实例演示二

  • 当 Redis 服务器出现异常情况时会导致什么后果?
  • 即 非正常关闭 Redis 服务器

1、此处我们使用 kill -9 命令来模拟异常情况的出现

  • 由上图可知,在 Redis 重启之后,key5 丢失!

2、打开并查看 dump.db 文件


总结:

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

实例演示三

  • 此处我们演示观察 自动触发(通过配置)生成 rdb 快照
  • 即在 Redis 配置文件中,设置让 Redis 每隔多长时间并产生多少次修改 就触发

1、执行 FLUSHALL 命令,清除前面测试的键值对(执行 FLUSHALL 也会清空 rdb 文件)


2、修改配置文件


3、重启服务器,并插入 2个键值对

注意:

  • redis 来说,修改配置文件之后,一定要重启服务器,才能生效!

4、等待 60秒,查看 dump.rdb 文件

  • 由上图可以,redis 成功生成 rdb "快照"

实例演示四

  • 如果将 rdb 文件故意改坏会导致什么后果?

1、手动的将 rdb 文件内容改坏


2、通过 kill -9 命令的方式重新启动 Redis 服务器

  • 由上图可知,Redis 服务器启动失败!

注意:

  • 如果仅通过 kill 命令的方式重启,就会在 Redis 服务器退出时,重新生成 rdb 快照
  • 此时新生成的 rdb 文件便会将刚改坏了的旧文件给替换掉
  • 因此无法观察到效果!

3、查看 Redis 的日志


具体解释:

  • rdb 文件为二进制文件
  • 上述操作所导致的后果为 直接改坏的 rdb 文件交给 Redis 去使用 
  • 此处得到的结果是不可预期的
  • 可能 Redis 服务器能启动,但是得到的数据可能正确也可能也有问题
  • 也有可能 Redis 服务器直接启动失败(如上述情况所示)

补充:

  • 但 Redis 提供了 rdb 文件的检查工具 ——> redis-check-rdb
  • 所以我们可以在启动 Redis 服务器之前,先通过 检查工具,检查 rdb 文件格式是否符合要求
  • 运行的时候,加入 rdb 文件作为命令行参数 ——> redis-check-rdb dump.rdb
  • 此时就是以检查工具的方式来运行,不会真的启动 redis 服务器

RDB 策略的优缺点

  • RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照,非常适用于备份、全量复制等场景,比如每 6小时执行 bgsave 备份,并把 RDB 文件复制到远程机器或者文件系统中
  • Redis 加载 RDB 恢复数据远远快于 AOF 方式
  • RDB 方式数据没办法做到实时持久化 或 秒级持久化,因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高
  • RDB 文件使用特定二进制格式保存,Redis 版本演变过程中有多个 RDB 版本,兼容性可能有风险

注意:

  • RDB 使用二进制的方式来组织数据,直接把主句读取到内存中,按照字节的格式取出来,并放到 结构体 / 对象 中即可
  • AOF 是通过文本的方式来组织数据的,则需要进行一系列的字符串切分操作

补充:

  • 一个老版本 Redis 的 rdb 文件,放到新版本 Reids 中不一定能识别的了
  • 在一般的实际工作当中,Redis 版本都是统一的
  • 如果确实有一些升级版本的需求,即遇到了不兼容的问题
  • 就可以通过写一个程序的方式,直接遍历旧 Redis 服务器中的所有 key,把数据取出来,插入到新 Reids 服务器中即可

总结:

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

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

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

相关文章

SeaTunnel 海量数据同步工具的使用(连载中……)

一、概述 SeaTunnel 是一个非常易用,高性能、支持实时流式和离线批处理的海量数据处理产品,前身是 WaterDrop (中文名:水滴),自 2021年10月12日更名为 SeaTunnel 。2021年12月9日,SeaTunnel 正式…

【Linux】Linux系统编程——pwd命令

文章目录 1.命令概述2.命令格式3.常用选项4.相关描述5.参考示例 1.命令概述 pwd(Print Working Directory)命令用于显示用户当前工作目录的完整路径。这是一个常用的命令,帮助用户确定他们目前所在的目录位置。 2.命令格式 基本的 pwd 命令…

STM32 USB OTG主机模式的实现方法

为了实现STM32的USB OTG主机模式,我们首先需要了解一些基本概念和原理,然后进行相应的硬件连接和软件编程。在这篇文章中,我们将介绍如何在STM32微控制器上实现USB OTG主机模式,并提供相应的代码示例。 1. STM32 USB OTG主机模式…

MyBatis 查询数据库

一. MyBatis 框架的搭建 本篇所用sql 表: drop table if exists userinfo; create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default ,createtime timestamp default current_tim…

教你用通义千问只要五步让千年的兵马俑跳上现代的科目三?

教你用五步让千年的兵马俑跳上现代的舞蹈科目三? 上面这个“科目三”的视频,只用了一张我上月去西安拍的兵马俑照片生成的。 使用通义千问,只要5步就能它舞动起来,跳上现在流行的“科目三”舞蹈。 全民舞王 第1步 打开通义千问…

【Spring实战】29 @Value 注解

文章目录 1. 定义2. 好处3. 示例1)注入基本类型2)注入集合类型3)使用默认值4)注入整数和其他类型 总结 在实际的应用中,我们经常需要从外部配置文件或其他配置源中获取参数值。Spring 框架提供了 Value 注解&#xff0…

《DAMA数据管理知识体系指南》05—第5章 数据建模和设计 知识点记录

第5章 数据建模和设计 5.1 引言 1.数据建模概要: 1)本章将描述数据模型的用途、数据建模中的基本概念和常用词汇以及数据建模的目标和原则。本章将使用一组与教育相关的数据作为案例来说明用各种数据建模的方法,并介绍它们之间的差异。 2&a…

如何用Mac工具制作“苹果高管形象照”

大伙儿最近有没有刷到“苹果高管形象照”风格,详细说来就是: 以苹果官网管理层简介页面中,各位高管形象照为模型,佐以磨皮、美白、高光等修图术,打造的看上去既有事业又有时间有氧的证件照,又称“苹…

OpenCV-25sobel算子(索贝尔算子)

前面所提到的滤波都是用于降噪的,去掉噪声,而算子是用来找边界,来识别图像的边缘。 一、概念 边缘是像素值发生跃迁的值,是图像的显著特点之一,在图像特征提取,对象检测,模式识别等方面都有重…

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…

Alist开源网盘搭建

官网:https://alist.nn.ci/zh/github下载地址:https://github.com/alist-org/alist/releases gitcode上也提供了源码:https://gitcode.com/mirrors/alist-org/alist/tags 源码安装使用自己研究,这里不讲解,较为复杂 我使⽤的版本:v3.29.1 我的下载地址:…

websocket项目 聊天室

1.项目概述 这个项目是一个基本的实时聊天应用,适用于小型团队或群体。提供了多个聊天室供用户选择。可以通过该代码进行进一步的扩展和定制,例如添加聊天机器人、改进界面等。 2.技术栈 flask,boostrapt,websocket&#xff0c…

大语言模型下载,huggingface和modelscope加速

huggingface 下载模型 如果服务器翻墙了,不用租机器 如果服务器没翻墙,可以建议使用下面的方式 可以租一台**autodl**不用显卡的机器,一小时只有1毛钱,启动学术加速,然后下载,下载完之后,用scp…

芯片烧写工具

问题描述 最近出了一个机器变砖的问题,一些用户使用的设备,头一天晚上用的好好的,第二天来一上电开机就起不来了。 然后就寄回来,返厂维修。一些是因为部分电子器件坏了,还有一些是文件系统问题,重新升级一…

GIT SourceTree 回滚提交

步骤一: 步骤二: 步骤三: 在终端输入命令(位置是项目目录下) git push origin feature_mo2.1_r3_zhanx653 -f

深圳三维扫描分析/偏差检测模具型腔三维尺寸及形位偏差测量公司

CASAIM中科广电三维扫描模具型腔深圳案例: 模具型腔的三维扫描分析/偏差检测是一项重要的质量控制过程,旨在确保模具制造过程中的精确度和一致性。 CASAIM中科广电通过使用高精度的三维扫描设备,可以获取模具型腔的实际形状和尺寸数据&…

Python - 深夜数据结构与算法之 LRUCache

目录 一.引言 二.LRU Cache 简介 1.实现特性 2.工作流程 三.LRU Cache 实战 1.HashMap ListNode 2.OrderedDict 四.总结 一.引言 LRU 即 Least Recently Used 意为最近使用,它是一种局部 Cache 的缓存方法,用于存储最近使用的元素,…

Java 实现双链表

文章目录 双链表(Doubly Linked List)是一种常用的数据结构,它与单链表相似,但每个节点除了包含指向下一个节点的指针外,还包含一个指向前一个节点的指针。 双链表的节点由三部分组成:数据域(存…

Sentinel 轨道数据及下载

Sentinel卫星轨道文件在处理Sentinel卫星数据时发挥着关键作用。这些轨道文件包含了有关卫星在轨道上的运动、位置、姿态等信息,对于地理校正、成像几何校正以及多时相分析等方面具有重要作用。以下是Sentinel卫星轨道文件的主要作用: 地理校正&#xff…

【机器学习300问】8、为什么要设计代价函数(损失函数)?它有什么用?

一、先介绍一下线性回归模型 (1)基本概念理解 文字解释:线性回归模型顾名思义,他处理的回归问题,是监督学习的一种。线性回归模型是一种预测模型,其基础是假设目标值和输入值之间存在线性关系。通过一条最…