【redis】什么是持久化之 RDB

什么是持久化

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

  1. 原子性
  2. 一致性
  3. 持久性==>持久化(说的一回事)
  • 把数据存储在硬盘上==>持久
  • 把数据存在内存上==>不持久
  • 重启进程/重启主机之后,数据是否还存在
  1. 隔离性

Redis 是一个内存数据库,是把数据存在内存中的。内存中的数据并不是持久的,要想能做到持久,就需要让 Redis 把数据存储在硬盘上

Redis 相比于 MySQL 这样的关系型数据库,最明显的有点/优势==>效率高/快

  • 因为它的数据是存在内存上的

如何实现持久化

为了保证速度快,数据肯定还得再内存中,但是为了持久,数据还得想办法存储在硬盘上

  • redis 决定,内存和硬盘上都存数据
  • 这样的两份数据,理论上是完全相同的(实际上可能存在一个小的概率有差异,取决于我们具体怎么进行持久化)

  • 当要插入一个新的数据的时候,就需要把这个数据,同时写入内存和硬盘。
    • 实际上怎么写入硬盘,还有不同的策略,不会导致每次都要写两份,导致效率降低
  • 当查询某个数据的时候,直接从内存读取
  • 硬盘的数据只是在 redis 重启的时候,用来恢复内存中的数据的
    这样就既能保证高效,又能通过硬盘恢复数据,保证持久化的效果,代价就是消耗了更多空间(一份数据,存了两遍)(硬盘便宜,不会带来太多成本)

实现策略

  1. RDB --> Redis DataBase
  2. AOF --> Append Only FIle

RDB

定期的把我们 Redis 内存中的数据,都给写入硬盘中,生成一个“快照

  • Redis 给内存中当前存储的这些数据,赶紧拍个照片,生成一个文件,存储在硬盘中
  • 后续 Redis 一旦重启了(内存数据就没了),就可以根据刚才的“快照”,把内存中的数据给恢复回来

[!quote] 快照
某个案发现场,警察来了之后,会拉上警戒线,然后开始忙碌地拍照,记录现场==>后续就可以根据这些记录的照片,来还原出现场当前发生了什么

定期”具体又分为两种方式:

  1. 手动触发
    • 程序员通过 Redis 客户端,执行特定的命令,来触发快照生成(savebgsave
  2. 自动触发
    • Redis 配置文件中,设置一下,让 Redis 每隔多长时间/每产生多少次修改就出发

手动触发

执行 save 的时候,Redis 就会全力以赴的进行“快照生成”操作,此时就会阻塞 Redis 的其他客户端的命令

  • 类似于 keys * 的后果
  • 一般不建议使用

save 是在前台,bgsavebackground)是在后面偷摸进行,不会影响 Redis 服务器处理其他客户端的请求和命令

  • 这样既可以保证持久化
  • 又可以保证 Redis 可以正常去响应命令

bgsave

Redis 是怎么做到 bgsave 的呢?是不是偷偷搞了个多线程?

  • 并非如此,多线程是实现并发编程的场景的一种方式,但不是唯一
  • Redis 使用的是“多进程”的方式,来完成的并发编程,实现 bgsave

image.png

Redis 服务器(父进程)收到 bgsave 的命令之后,首先会进行一个判断

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

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


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

forkLinux 系统提供的一个创建子进程的 API

  • 如果是其他系统,比如 Windows,创建子进程就不是 forkCreatProcess
  • fork 创建子进程,简单粗暴,就是直接把当前的进程(父进程)复制一份,作为子进程。一旦复制完成了,父子进程就是两个独立的进程,就格子执行各自的了
    • 会复制 PCB、虚拟地址空间(内存中的数据)、文件描述附表…
    • 本来 redis server 中,有若干变量,保存了一些键值对数据。随着这样的 fork 的进行,子进程的这个内存里也会存在和刚才父进程中一模一样的变量

因此,复制出来的“克隆体“(子进程),内存中的数据就是和“本体”(父进程)是一样的。接下来安排子进程去进行“持久化”操作,也就相当于把父进程本体这里的数据给持久化了

父进程打开了一个文件,fork 了之后,子进程也是可以同时使用这个文件的

  • 导致了子进程持久化写入的那个文件,和父进程本来要写的文件是同一个

如果当前 redis 服务器中存储的数据特别多,内存消耗特别大,此时进行上述的复制操作,是否会有很大的性能开销?

  • 此处的性能开销其实挺小
  • fork 在进行内存拷贝的时候,不是简单无脑的直接把所有的数据都拷贝一遍,而是“写实拷贝”的机制来完成的
    • 如果子进程里的这个内存数据,和父进程的内存数据完全一样,此时就不会触发真正的拷贝动作(而是爷俩其实用一份内存数据)
    • 但是,其实这俩进程的内存空间,应该是各自独立的。一旦某一方针对这个数据进行了修改,就会立即触发真正的物理内存上的数据拷贝

在进行 bgsave 这个场景中,绝大部分的内存数据,是不需要进行改变的(整体来说这个过程执行的还挺快,这个短时间内,父进程中不会有大批的内存数据变化)

因此,子进程的“写实拷贝”不会触发很多次,也就保证了整体的“拷贝时间”是可控的,高效的


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

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

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

  • 子进程不好观察,我们观察新旧文件(通过 stat 命令,查看文件的 inode 号)

RDB 文件

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

image.png

  • RDB 机制生成的镜像文件,redis 服务器默认就是开启了 RDB
  • 这是一个二进制文件,把内存中的数据,以压缩(消耗一定 CPU 资源,但是能省空间)的形式,保存到这个二进制文件中
    • 最多打开看看就行了,不要乱改,一旦要是把数据的格式改坏了,就麻烦了
    • 后续 redis 服务器重新启动,就会尝试加载这个 RDB 文件,如果发现格式错误,就可能会加载数据失败

redis 提供了 RDB 文件的检查工具image.png|256

当执行生成 RDB 镜像操作的时候,此时就会把要生产的快照数据,先保存到一个临时文件中。当这个快照生成完毕之后,再删除之前的 RDB 文件,把新生成的临时的 RDB 文件名字改成刚才的 dump.rdb

  • 自始至终,RDB 文件始终只有一个

效果

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

  • image.png|438
  • 插入数据之后,观察 RDB 文件内容 image.png image.png|427
  • 发现没有变化,此时我们执行保存数据的命令image.png
    image.png|331

可以发现 RDB 文件内容更新了


RDB 的触发时机:

  1. 手动(save、bgsave)
  2. 自动(配置文件中,进行设置)

image.png

  • 900s 之后,并且至少存在一次 key 的修改,就会触发自动更新

这些数值都是可以自由修改的,但是此处修改数据的时候,有一个基本的原则:

  • 生成一次 RDB 快照,这个成本较高,不能让这个操作执行太频繁

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

  1. 通过刚才配置文件中 save 执行 M 时间内,修改 N
  2. 通过 shutdown 命令(redis 里的一个命令)关闭 redis 服务器,也会触发(service redis-server restart)(正常关闭
  3. redis 进行主从复制的时候,主节点也会自动生成 RDB 快照,然后把 RDB 快照文件内容传输给从节点
  • 如果是通过正常流程重新启动 redis 服务器,此时 redis 服务器会在退出的时候,自动触发生成 RDB 操作
  • 但如果是异常重启(kill -9 或者服务器掉电),此时 redis 服务器来不及生成 RDB,内存中尚未保存到快照中的数据,就会随着重启而丢失
  • 若要修改 RDB 配置,修改完成后需要重启服务器
  • 如果 RDB 文件被改坏了,redis 服务器启动不了了,我们可以去看一下日志,查看报错信息

redis 提供了 RDB 文件的检查工具,可以先通过检查工具,检查一下 RDB 文件格式是否符合要求 image.png|301

  • 检查工具和 reids 服务器,在 5.0 版本是同一个可执行程序,但是我们可以在运行的时候加上不同选项
  • 在运行的时候,加上 RDB 文件作为命令行参数,此时就是以检查工具的方式来运行

image.png

  • 这里就显示 RDB 文件里面有错误

RDB 小结

  • RDB 是一个紧凑压缩的二进制文件,代表 redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每 6 小时执行 bgsave 备份,并把 RDB 文件复制到远程机器或者文件系统中(如 hdfs)用于灾备
  • redis 加载 RDB 恢复数据远远快于 AOF 的方式
    • RDB 是使用二进制的方式来组织数据,直接把数据读取到内存中,按照字节的格式取出来,放到结构体/对象中即可
    • AOF 是使用文本的方式来组织数据
  • RDB 方式数据没办法做到实时持久化,因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高
  • RDB 文件使用特定二进制格式保存,redis 版本演进过程中有多个 RDB 版本,兼容性可能有风险
    • 老版本的 redisRDB 文件,放到新版本的 redis 中不一定能识别

如果确实需要有一些“升级版本”的需求,就可以通过写一个程序的方式,直接遍历旧的 redis 中的所有 key,把数据取出来,插入到新的 redis 服务器中即可

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

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

相关文章

Python、MATLAB和PPT完成数学建模竞赛中的地图绘制

参加数学建模比赛时,很多题目——诸如统计类、数据挖掘类、环保类、建议类的题目总会涉及到地理相关的情景,往往要求我们制作与地图相关的可视化内容。如下图,这是21年亚太赛的那道塞罕坝的题目,期间涉及到温度、降水和森林覆盖率…

Python(冒泡排序、选择排序、插入法排序、快速排序,算法稳定性)

算法的稳定性 冒泡排序 # 冒泡排序 # 1 思想: 相邻位置两个元素比较, 前面的元素比后面的元素大则交换, 把最大的数给找到 # 经过一轮一轮的比较最终把序列给排序 # 2 关键点1: 两层for循环 外层循环控制多少轮 内层for循环控制比较次数 # 3 关键点2: 若遍历一遍没有数字…

【自用】NLP算法面经(5)

一、L1、L2正则化 正则化是机器学习中用于防止过拟合并提高模型泛化能力的技术。当模型过拟合时,它已经很好地学习了训练数据,甚至是训练数据中的噪声,所以可能无法在新的、未见过的数据上表现良好。 比如: 其中,x1和…

PyCharm安装redis,python安装redis,PyCharm使用失败问题

报错信息 Usage: D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] -r [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip instal…

学习笔记|arduino uno r3|DS1307时钟芯片|Atmega328P| 设置时间|读取时间|无源晶振:DS1307时钟芯片实验

目录 芯片pinout: 实验器件: 实验连线 解决AVR 架构不支持 printf() 方法 使用GetTimeAndDate.ino设置时间: 使用SetTimeAndDate.ino设置时间: 芯片pinout: DS1307 是美国 DALLAS 公司推出的 I 总线接口实时时钟芯…

uniapp可拖拽消息数徽标draggable-badge,仿手机qq聊天列表未读数徽标动效

组件下载地址:https://ext.dcloud.net.cn/plugin?id22679 兼容性: 测试了h5和微信小程序,理论支持全平台,暂不支持pc端,不过可以自己修改事件兼容pc 使用uniapp仿写了一个手机qq聊天列表右侧未读数的徽标组件&#x…

【设计模式】策略模式

以下是格式优化后的Markdown文档,仅调整代码缩进,保持内容不变: 四、策略模式 策略(Strategy) 模式是一种行为型模式,其实现过程与模板方法模式非常类似——都 是以扩展的方式支持未来的变化。本章通过对一个具体范例的逐步重构…

STM32配套程序接线图

1 工程模板 2 LED闪烁 3LED流水灯 4蜂鸣器 5按键控制LED 6光敏传感器控制蜂鸣器 7OLED显示屏 8对射式红外传感器计次 9旋转编码器计次 10 定时器定时中断 11定时器外部时钟 12PWM驱动LED呼吸灯 13 PWM驱动舵机 14 PWM驱动直流电机 15输入捕获模式测频率 16PWMI模式测频率占空…

【C语言】使用结构体实现位段

一、位段 前面我们学习了结构体,位段的声明和结构体是一样的,其区别如下: 1、位段的成员必须是int 、unsigned int 、signed int 、在C99中位段的成员的类型也可以选择其他类型。 2、位段的成员名后边有一个冒号和一个数字 如下&#xff…

【大模型系列篇】硅基智能开源数字人模型HeyGem.ai,开启数字人时刻

硅基智能开源数字人模型HeyGem.ai, 1秒克隆生成4K视频, 支持离线多语言, 开源72小时狂揽1.3k星, 目前已经获得3.4k星。 硅基智能正式宣布在GitHub开源全球TOP级数字人模型,同时发布基于该模型的同名数字人工具硅基数字人克隆的本地安装包,这一举措标志着…

【C++】STL库面试常问点

STL库 什么是STL库 C标准模板库(Standard Template Libiary)基于泛型编程(模板),实现常见的数据结构和算法,提升代码的复用性和效率。 STL库有哪些组件 STL库由以下组件构成: ● 容器&#xf…

knowledge-微前端(多个前端应用聚合的一个应用架构体系,每个小的应用可独立运行,独立开发,独立部署上线)

1.前言 微前端,将一个大的前端应用拆分为多个小型的,独立开发的前端应用,每一个小型的应用都可以单独的开发,部署和运行。这种结构允许不同的团队使用不同的技术栈来开发应用的不同部分,提高开发的效率与灵活性。 2.实…

三格电子PLC数据采集网关-工业互联的智能枢纽

在工业自动化领域,设备间的数据互通与协议兼容是核心挑战之一。三格电子推出的PLC据采集网关SG-PLC-Private,凭借其多协议兼容、高稳定性和灵活配置能力,成为工业物联网(IIoT)中实现设备互联的关键设备。本文将从产品功…

鸿蒙NEXT项目实战-百得知识库05

代码仓地址,大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点: 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…

leetcode热题100道——字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat", &…

【Vue3】01-vue3的基础 + ref reactive

首先确保已经有了ES6的基础 本文介绍 vue 的基础使用以及 两种响应数据的方式。 目录 1. 创建一个vue应用程序 2. Vue模块化开发 3. ref 和 reactive 的区别 1. 创建一个vue应用程序 所需的两个文件: https://unpkg.com/vue3/dist/vue.global.js https://un…

Linux中的selinux,磁盘管理

一、selinux 作用:通过对软件进程限制某些权限,从而保证系统的安全。通过上下文类型和设定好的上下文类型是否一致。如果一致,那么软件就可以完成后续的操作,例如访问文件中数据,或者让数据通过某个端口。做好个人防护…

Linux应用:Linux的信号

什么是信号 信号是一种软件中断,用于通知进程系统中发生了某种特定事件。它是操作系统与进程之间,以及进程与进程之间进行异步通信的一种方式。在 Linux 系统中,信号是一种比较简单的进程间通信机制。当一个信号产生时,内核会通过…

Linux笔记之Ubuntu22.04安装IBus中文输入法教程

Linux笔记之Ubuntu22.04安装IBus中文输入法教程 code review! 文章目录 Linux笔记之Ubuntu22.04安装IBus中文输入法教程安装 IBus 并配置中文输入法步骤 1: 安装 IBus 和拼音插件步骤 2: 设置 IBus 为默认输入法框架步骤 3: 重启会话步骤 4: 添加中文输入法步骤 5: …

【AIGC前沿】MiniMax海螺AI视频——图片/文本生成高质量视频

目录 1.MiniMax海螺AI视频简介 2.使用教程 1.MiniMax海螺AI视频简介 海螺视频,作为 MiniMax 旗下海螺 AI 平台精心打造的 AI 视频生成工具,致力于助力用户产出高品质视频内容。该工具依托 abab-video-1 模型,具备强大的文生视频功能。用户…