redis设计与实现(五)RDB与AOF持久化

RDB持久化

因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。

为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。

RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态 RDB文件是保存在硬盘里的

  • 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。

  • 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。

SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求

和SAVE命令直接阻塞服务器进程的做法不同,BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求

服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。

RDB文件结构

每个非空数据库在RDB文件中都可以保存为SELECTDB、db_number、key_value_pairs三个部分

  • SELECTDB常量的长度为1字节,当读入程序遇到这个值的时候,它知道接下来要读入的将是一个数据库号码。
  • db_number保存着一个数据库号码,根据号码的大小不同,这个部分的长度可以是1字节、2字节或者5字节。当程序读入db_number部分之后,服务器会调用SELECT命令,根据读入的数据库号码进行数据库切换,使得之后读入的键值对可以载入到正确的数据库中。
  • key_value_pairs部分保存了数据库中的所有键值对数据,如果键值对带有过期时间,那么过期时间也会和键值对保存在一起。根据键值对的数量、类型、内容以及是否有过期时间等条件的不同,key_value_pairs部分的长度也会有所不同。
  • RDB文件中的每个key_value_pairs部分都保存了一个或以上数量的键值对,如果键值对带有过期时间的话,那么键值对的过期时间也会被保存在内。不带过期时间的键值对在RDB文件中由TYPE、key、value三部分组成。

AOF持久化

与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。

在这里插入图片描述

AOF持久化的实现:

AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤。

  • 当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾

为了提高文件的写入效率,在现代操作系统中,当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。

但是若计算机发生停机,那么保存在内存缓冲区里面的写入数据将会丢失。

为此,系统提供了fsyncfdatasync两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性

因为AOF文件里面包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。

AOF重写:

因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,AOF文件中的内容会越来越多,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响,并且AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。

为此Redis提供了AOF文件重写功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积要小得多。

但实际上,AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库状态来实现的。

首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是AOF重写功能的实现原理。

在实际中,为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序在处理列表、哈希表、集合、有序集合这四种可能会带有多个元素的键时,会先检查键所包含的元素数量,如果元素的数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD常量的值,那么重写程序将使用多条命令来记录键的值,而不单单使用一条命令。

作为一种辅佐性的维护手段,Redis不希望AOF重写造成服务器无法处理请求,所以Redis决定将AOF重写程序放到子进程里执行,这样做可以同时达到两个目的:

  • 子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。

  • 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。

不过,使用子进程也有一个问题需要解决,因为子进程在进行AOF重写期间,服务器进程还需要继续处理命令请求,而新的命令可能会对现有的数据库状态进行修改,从而使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个信号处理函数,并执行以下工作:

  • 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。

  • 对新的AOF文件进行改名,原子地(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

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

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

相关文章

如何定位检查不到的元素

光标离开输入框时,输入框立刻消失,导致无法查看该元素的html标签属性,如何定位这种元素呢?有两种方法,一种是通过事件监听器,另一种是通过网络接口抓包 1、首先定位到搜索按钮 这个搜索的按钮,当…

鸿蒙低代码开发的局限性

在版本是DevEco Studio 3.1.1 Release,SDK是3.1.0(API9) 的基础上。 1、低代码插件没有WebView组件。 2、低代码插件没有空白的自定义组件,当前提供的所谓自定义组件,只能用列表中提供的组件来拼接新的组件。 3、使用ets代码自定义的组件&…

PyTorch 张量数据类型

【数据类型】Python 与 PyTorch 常见数据类型对应: 用 a.type() 获取数据类型,用 isinstance(a, 目标类型) 进行类型合法化检测 >>> import torch >>> a torch.randn(2,3) >>> a tensor([[-1.7818, -0.2472, -2.0684],[ 0.…

Java高手的30k之路|面试宝典|精通PriorityQueue优先队列

PriorityQueue PriorityQueue 是 Java 集合框架中的一个队列实现,基于优先级堆(优先队列),它能够保证每次出队的元素都是当前队列中优先级最高的元素(对于最小堆而言,优先级最高即为最小值)。其…

(Javascript)AI数字人mp4转canvas播放并去除背景绿幕

1、需求介绍 H5页面嵌入AI数字人播报&#xff0c;但生成的数字人是mp4格式且有绿幕背景&#xff0c;需要转成canvas并去除背景&#xff1b; 2、效果&#xff1a; 去除前&#xff1a; 去除后&#xff1a; 3、代码 <!DOCTYPE html> <html lang"en"><…

上位机能不能替代PLC实现控制?为什么一定要学上位机?

上位机是一个广泛用于自动化控制系统的术语&#xff0c;它通常指的是在自动化控制系统中&#xff0c;用于监控和控制下位机&#xff08;通常是嵌入式系统或者是PLC等&#xff09;的计算机系统。上位机可以通过各种通信协议&#xff08;如RS232、RS485、以太网等&#xff09;与下…

C端设计师去做B端界面设计易犯哪些?要不要给他提个醒。

2024-03-29 17:03大美B端工场 很多C端设计师初涉B端设计&#xff0c;思路转变不过来&#xff0c;还用C端思想指导B端设计&#xff0c;结果就是总感觉不舒服&#xff0c;大美B端工场&#xff0c;为大家详细解读一下。 当C端设计师去设计B端界面时&#xff0c;可能会经常犯以下…

【React】在 react 应用中,怎么使用useReducer

在 React 应用中,useReducer 是一个 Hook,它允许你使用 reducer 函数来管理组件的本地状态。Reducer 类似于 Redux 中的 reducer,它接收当前的状态和一个动作(action),并返回一个新的状态。 下面是如何在 React 组件中使用 useReducer 的步骤: 导入 useReducer:import…

C++面向对象程序设计 - 函数库

C语言程序中各种功能基本上都是由函数来实现的&#xff0c;在C语言的发展过程中建立了功能丰富的函数库&#xff0c;C从C语言继承了些函数功能。如果要用函数库中的函数&#xff0c;就必须在程序文件中包含文件中有关的头文件&#xff0c;在不同的头文件中&#xff0c;包含了不…

时间复杂度与空间复杂度题目讲解

前言&#xff1a; 在前面我们了解到了时间复杂度与空间复杂度&#xff0c;这里我们就可以尝试一下做一些关于时间复杂度与空间复杂度的题目。 1. 数组篇 题目一&#xff1a;消失的数字 消失的数字&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 看…

Elixir学习笔记——进程(Processes)

在 Elixir 中&#xff0c;所有代码都在进程内运行。进程彼此隔离&#xff0c;彼此并发运行并通过消息传递进行通信。进程不仅是 Elixir 中并发的基础&#xff0c;而且还提供了构建分布式和容错程序的方法。 Elixir 的进程不应与操作系统进程混淆。Elixir 中的进程在内存和 CPU…

Fastweb - Lua操作SQLite数据库

本文演示FastWeb网站开发中处理SQLite数据库 示例演示如何创建、查询、删除与更新&#xff0c;SQL在文章底部。 local dkjson require("dkjson") local db sqlite_db.new() -- 清空示例 function sqlite_delete()-- 清空数据local ppst db:setsql("DELETE …

进程的创建和管理

一. 实验内容 1&#xff0e; 编写一个程序&#xff0c;程序中创建一个子进程。然后父、子进程各自独立运行&#xff0c;父进程不断地在标准输出设备&#xff08;即显示器&#xff09;上输出字母p和回车&#xff08;输出30次或以上&#xff09;&#xff0c;子进程不断地在标准输…

[面试题]Java【并发】

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL 因为 Java 并发涉及到的内容会非常多&#xff0c;本面试题可能很难覆盖到所有的知识点&#xff0c;所以推荐 《Java并发编程的艺术》 。 Java 线程 线程 通知 等待 线…

植物ATAC-seq文献集锦(三)——果实发育篇

ATAC-seq在植物研究领域的应用我们已经介绍2期了&#xff0c;本期我们聚焦ATAC-seq技术在果实发育方向的应用案例。 植物ATAC-seq文献集锦&#xff08;一&#xff09;——基因组篇 植物ATAC-seq文献集锦&#xff08;二&#xff09;——生长发育篇 文献一&#xff1a;Ident…

数据结构篇:链表和树结构的操作方法

本节课在线学习视频&#xff08;网盘地址&#xff0c;保存后即可免费观看&#xff09;&#xff1a; ​​https://pan.quark.cn/s/e4f2ff1e1895​​ 链表和树是数据结构中两种非常重要和常见的结构。链表是一种线性数据结构&#xff0c;适用于需要频繁插入和删除操作的场景&am…

Linux 内核 (十二)进程间通讯 之 消息队列

前言 这个系列的上一篇介绍了进程间通讯关于管道相关的内容及代码实例,本章要介绍关于消息队列相关的内容. 消息队列交互图示 函数原型 #include <sys/msg.h> #include <sys/ipc.h> //创建 or 打开队列 成功返回队列ID,失败返回-1 int msgget(key_t key,int fla…

商城小程序系统:一站式搭建,轻松上线

前言 近年来&#xff0c;商城小程序系统以其便捷、高效的特点&#xff0c;正逐渐成为商品买卖的新宠。这类小程序&#xff0c;类似于我们熟知的京东、淘宝等电商巨头&#xff0c;为商家提供了一个全新的销售渠道&#xff0c;让商品买卖更加智能化、便捷化。 一、商城小程序有什…

【Linux】从零开始配置新的服务器的机器学习环境

终端远程登录 ssh -p [端口号] [服务器用户名][服务器IP]或者 ssh [用户名][主机地址]第二种的前提是在.ssh\config中配置了host 安装文本编辑器vim 主要用于后续的文本编辑&#xff0c;个人比较习惯用vim&#xff0c;根据自己喜好选择 更新apt sudo apt update安装文本编辑…

苹果安卓网页的H5封装成App的应用和原生开发的应用有什么不一样?

H5封装类成App的应用和原生应用有什么不一样&#xff1f;——一对比谈优缺点 1. 开发速度和复用性 H5封装的App优势&#xff1a;一次编写&#xff0c;多平台运行。你只需要使用一种语言编写代码&#xff0c;就可以发布到不同的平台&#xff0c;降低开发成本。 原生应用优势&…