【Redis】持久化机制--RDB和AOF

目录

1. RDB持久化

1.1 触发机制

 1.2 流程说明

1.3 RDB文件的处理

1.4 RDB机制演示

1.5 RDB的优缺点

2. AOF持久化

2.1 使用AOF与基本演示

2.2 AOF的工作流程

 2.3 文件同步(缓冲区刷新策略)

2.4 重写机制

2.5 AOF重写流程

 2.6 启动时数据恢复


持久化功能有效地避免因进程退出造成数据丢失问题当下次重启时利用之前持久化的文件即可实现数据恢复,(比如重启机器、机器故障之后恢复数据),或者是为了做数据同步(比如 Redis 集群的主从节点通过 RDB 文件同步数据)。

Redis 不同于 Memcached 的很重要一点就是,Redis 支持持久化,而且支持 3 种持久化方式:

  • 快照(snapshotting,RDB)
  • 只追加文件(append-only file, AOF)
  • RDB 和 AOF 的混合持久化(Redis 4.0 新增)


1. RDB持久化

RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB持久化过程分为手动触发和自动触发。Redis 创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis 主从结构,主要用来提高 Redis 性能),还可以将快照留在原地以便重启服务器的时候使用。

1.1 触发机制

1. 手动触发分别对应 save 和 bgsave 命令:

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

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

2. Redis 自动触发 RDB 持久化机制,这个触发机制才是在实战中有价值的。

  • 使用 save 配置。如"save m n" 表示 m 秒内数据集发生了n次修改,自动 RDB 持久化。(快照持久化是 Redis 默认采用的持久化方式,在 redis.conf 配置文件中默认有此下配置,后见1.4小节会详细讲)
  • 从节点进行全量复制操作时,主节点自动进行 RDB 持久化,随后将 RDB 文件内容发送给从结点。
  • 执行 shutdown 命令关闭 Redis 时,执行 RDB 持久化。

 1.2 流程说明

 bgsave 是主流的 RDB 持久化方式,上图是它的运作流程。

  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服务器中存储的数据特别多,内存消耗特别大(比如100GB),此时,进行上述的fork操作,是否会有很大的性能开销?

答:此时的性能开销,其实是挺小的。fork在进行内存拷贝的时候,不是简单无脑的直接把所有的数据都拷贝一遍,而是“写时拷贝”的机制来完成的!

具体来说,fork只会在内存被修改时才实际复制数据,而在未修改时,父子进程共享同一份物理内存。因此,即使有大量数据,内存的实际拷贝成本也能得到控制,从而在处理高内存使用情况下的性能影响降到最低。这使得Redis在高负载时仍然能够有效运行。

1.3 RDB文件的处理

保存

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

 打开目录看一看:

这里的 dump.rdb就是rbd机制生成的文件,以压缩的方式,保存到二进制文件中。(压缩需要消耗一定的cpu资源,但是能够节省存储空间)(Redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数 config set rdbcompression {yes|no} 动态修改。)

rbd持久化是可以被多次触发的,那么这个dump.rdb文件按照什么机制来“完成”的呢?

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


校验

如果 Redis 启动时加载到损坏的 RDB 文件会拒绝启动。这时可以使用 Redis 提供的 redis-check-dump 工具检测 RDB 文件并获取对应的错误报告。

这里的redis-check-rdb* 就是检查工具。


1.4 RDB机制演示

1. 连接到redis,清空数据,观察工作目录(/var/lib/redis)下的dump.rdb大概是什么样子:

2. 插入几个key-value数据,再次观察rdb文件:

此时看到是没有变化的,这是因为rdb触发时机并不是插入后就会立即更新的。我们前面提到手动触发和命令触发,两种方式都没能达到啊。手动触发没有使用可以理解,那么自动触发的条件究竟是怎么触发呢?

继续来看看redis的配置文件,在/etc/redis/redis.conf

save 900 1           #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。save 300 10          #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。save 60 10000        #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。

可见我们现在的修改确实达不到,任何一种自动触发机制。【配置文件中的数值可以修改,但是要注意,修改的基本原则就是:生成一次rbd是一个比较高的成本,不宜让这个操作的执行过于频繁】

3. 手动触发RDB

虽然是二进制文件,但是隐隐约约才是能够看到rdb文件确实发生了变化。我们可以重启redis服务器来观察是否重启后,可以通过持久化的RDB文件来恢复数据。

4. 重启Redis,观察持久化是否成功

可以看到数据确实恢复了,哪怕redsi服务器重启,数据也是不会丢失的。因为它加载了rdb文件中的内容恢复到了之前的状态。

如果插入新的key后,没有通过手动bgsave来触发RDB机制,这时候重新启动Redis,服务中新添加的数据就会丢失。那么是不是这样的呢?

其实并不是这样的,除了手动触发之外:

  • 通过刚才配置文件中 save 执行 M 时间内,修改 N 次.…..
  • 通过 shutdown 命令(redis 里的一个命令) 关闭 redis 服务器,也会触发.(service redis-server restart)
  • redis 进行主从复制的对候,主节点也会自动生成 rdb 快照,然后把 rdb 快照文件内容传输给从节点

5. 继续添加新元素,然后使用service redis-server restart 重启服务

除了手动执行bgsave之外,也可以通过配置save配置文件来修改自动触发的条件。这里就不再演示。

1.5 RDB的优缺点

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

2. AOF持久化

AOF(Append Only File)持久化: 以独立日志的方式记录每次写命令,重启时再重新执行 AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是
Redis 持久化的主流方式。(当开启AOF后,RDB就不再生效)

2.1 使用AOF与基本演示

AOF默认是不开启的,需要通过配置文件配置:appendonly yes后,开启AOF。

修改完配置文件后,重启服务:service redis-server restart

添加新的数据

暴力kill redis服务,是否会恢复数据?

 从图中结果来看,数据是不会丢失的。符合我们的预期,以上就是大概的AOF持久化机制的基本使用过程。

2.2 AOF的工作流程

1. 所有的写⼊命令会追加到 aof_buf(缓冲区)中。
2. AOF 缓冲区根据对应的策略向硬盘做 同步操作 。 (具体是哪些文件同步策略下文2.3会详细介绍)这样可以减少写磁盘的次数。【缓冲区还是为了追求高的效率,如果 突然断电 ,缓冲区中的数据还没有来得及写磁盘,这时候还是会出现 数据丢失 的情况的】
3. 随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件进⾏ 重写 ,达到压缩的⽬的。
4. 当 Redis 服务器启动时,可以加载 AOF ⽂件进⾏数据恢复。

 2.3 文件同步(缓冲区刷新策略)

Redis 提供了多种 AOF 缓冲区同步文件策略,由参数 appendfsync控制,不同值的含义如下所
示。刷新频率越高,性能影响就越大,同时数据的可靠性也就越高;反之则反。

always:刷新频率最高,数据的可靠性最高,但是性能最低;

everysec:刷新频率低一丢丢,数据的可靠性稍降低,性能同时稍高;(默认刷新方式

no:频率最低,数据可靠性也是最低,但是性能是最好的。

2.4 重写机制

随着命令不断写入AOF,文件会越来越大(redis重启后需要读取aof内容,太大的话肯定影响效率),为了解决这个问题,Redis 引入 AOF 重写机制压缩文件体积。AOF文件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF文件。重写后的 AOF为什么可以变小?有如下原因:

  • 进程内已超时的数据不再写入文件。
  • 旧的 AOF 中的无效命令,例如 del、hdel、srem 等重写后将会删除,只需要保留数据的最终版本。
  • 多条写操作合并为一条,例如lpush list a、lpush listb、lpush list 从可以合并为 lpush list a b c.

整体的思想就是剔除其中冗余的操作,并且合并一些操作(记录最终状态),能够达到aof的文件“瘦身”效果。

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

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

当触发了AOF重写时,就会通过运行流程来执行重写。2.5节所示

2.5 AOF重写流程

 2.6 启动时数据恢复

当Redis启动的时候,会根据RDB和AOF文件的内容,进行数据恢复。


3. 总结

1. RDB(Redis Database)快照

优点

  • 性能影响较小:RDB持久化的过程由Redis在后台子进程执行,因此对主进程的读写性能影响较小。
  • 数据恢复速度快:由于RDB文件是一个紧凑的二进制文件,可以快速加载到内存中,因此数据恢复速度通常比AOF更快。
  • 适用于定期备份:RDB文件是完整的数据快照,适合用于定期全量备份,便于长期数据保存和迁移。

缺点

  • 数据丢失风险较高:RDB是定期执行的(默认每5分钟或1小时执行一次,视配置而定),因此在两次快照之间的数据将会丢失。如果Redis在快照完成之前崩溃,会导致最新的数据丢失。
  • 不灵活:RDB持久化只能定期执行,无法根据实际业务需求灵活地设置持久化频率。

2. AOF(Append-Only File)

优点

  • 数据丢失风险低:AOF记录每个写操作的日志,并支持多种同步策略(如每次写操作、每秒写操作、操作系统自动同步等),可以实现较高的数据持久化频率,最大程度减少数据丢失。
  • 更可控的持久化机制:AOF提供多种同步方式,用户可以根据性能与数据安全的需求调整同步频率,获得灵活的持久化控制。
  • 文件内容可读:AOF文件是以Redis命令格式保存的,具有可读性,方便用户对数据进行恢复和诊断。

缺点

  • 文件体积大:由于AOF会记录每一条写操作指令,随着时间的推移,文件会比RDB大得多,导致持久化文件占用大量磁盘空间。
  • 数据恢复速度较慢:AOF文件在恢复时需要逐条执行日志中的命令,因此恢复速度通常比RDB慢。
  • 对性能影响更大:频繁的写操作会导致性能开销,尤其是在设置为“每次写操作”同步时,对Redis的性能影响较大。

总结

  • RDB适用于:希望最小化对Redis性能影响、对数据持久化频率要求不高,或者需要定期备份的场景。
  • AOF适用于:对数据持久性要求高,不能接受较多数据丢失的场景,但需要注意性能和磁盘空间的占用。

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

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

相关文章

产品需求-聊天框中发送的文件,要求文件名过长是保留后缀名省略中间的文字部分

介绍一下之前做过的一个需求,是要实现pc的一个聊天软件的消息引用功能。对于文件的引用,产品是这样做要求的: 消息框无固定长度,根据回复的文字长度决定消息框长度对于一个pc项目,当页面窗口变化时要实现响应式文件名…

C++入门day5-面向对象编程(终)

C入门day4-面向对象编程(下)-CSDN博客 本节是我们面向对象内容的最终篇章,不是说我们的C就学到这里。如果有一些面向对象的基础知识没有讲到,后面会发布在知识点补充专栏,全都是干货满满的。 https://blog.csdn.net/u…

小学生管理系统项目

在当今数字化教育的背景下,小学生管理系统应运而生。本项目采用 JSP Servlet JDBC MySQL 的技术组合,并在开发工具 Idea 和 Eclipse 的辅助下,结合数据库管理工具 Navicat 进行开发。 一、系统入口 用户登录入口:为普通用户提…

可看见车辆行人的高清实时视频第2辑

我们在《看见车辆行人的高清实时视频第2辑》分享了10处可看见车辆行人的实时动态高清视频。 现在我们又整理10处为你分享可看见车辆行人的实时动态高清视频,一共有30个摄像头数据,这些视频来自公开的高清摄像头实时直播画面。 我们在文末为你分享了这些…

低代码平台推荐与对比,国内外哪家更胜一筹?

低代码开发通过图形界面简化开发,提升速度与协作,降低成本。国内外平台如ZohoCreator、OutSystems等各具特色,支持快速开发、集成与数据安全。企业可试用后按需选择,降低决策成本。 一、低代码是什么? 低代码开发是一…

webpack 4 的 30 个步骤构建 react 开发环境

将 react 和 webpack4 进行结合,集 webpack 的优势于一身,从 0 开始构建一个强大的 react 开发环境。 其实很多人都有 一看就会,一做就废 的特点(当然也包括我在内),这个时候,你需要制定一个略微详细的计划&#xff0…

C++的成员初始化列表

1、构造函数初始化列表,这是我们在构造函数中初始化类成员(变量)的一种方式,因此,当我们编写一个类并向该类添加成员时,通常需要用某种方式对这些成员(变量)进行初始化。 通常在构造…

Efficient DETR: Improving End-to-End Object Detector with Dense Prior

原文链接 [2104.01318] Efficient DETR: Improving End-to-End Object Detector with Dense Prior (arxiv.org)https://arxiv.org/abs/2104.01318 原文笔记 What 1、一种针对DETR的objectquery初始化的方法 2、针对Deformable DETR进行改进,改进之后的模型具有…

【工具分享】FONIX勒索病毒解密工具

前言 FONIX勒索软件首次出现在2020年6月,并迅速成为勒索即服务(RaaS)平台的一部分。尽管它最初的影响力有限,FONIX从2020年11月开始显著增加了攻击频率。FONIX以其复杂的加密方法著称,使用了AES、Salsa20、ChaCha和RS…

【HarmonyOS】自定义圆点进度条

【HarmonyOS】实现一个自定义带圆点的进度条效果。 方案就是做一个圆角组件,然后利用rotate旋转,至于动画效果,我查了一下文档,只要设置enableSmoothEffect:false,就可以关闭动画,然后自己开个定时器&#…

鸿蒙开发(NEXT/API 12)【硬件(接入手写套件)】手写功能开发

接入手写套件后,可以在应用中创建手写功能界面。界面包括手写画布和笔刷工具栏两部分,手写画布部分支持手写笔和手指的书写效果绘制,笔刷工具栏部分提供多种笔刷和编辑工具,并支持对手写功能进行设置。接入手写套件后将自动开启一…

C++:采用模板封装顺序表,栈,队列

1.顺序表&#xff1a; list.hpp #ifndef LIST_HPP #define LIST_HPP #include <iostream>using namespace std;template <class L>class Seqlist { private:L *ptr;L size;L len0;public:void init(L n){//堆区申请空间&#xff08;大小为n&#xff09;this->…

基于STM32的智能空气质量监测系统

目录 引言项目背景环境准备 硬件准备软件安装与配置系统设计 系统架构关键技术代码示例 传感器数据采集空气质量监测与控制实现实时数据显示与报警系统应用场景结论 1. 引言 空气质量对人类健康有着重要的影响&#xff0c;尤其是在污染较严重的地区。智能空气质量监测系统通…

点餐小程序实战教程12菜品展示

目录 1 点餐界面2 显示菜品分类2.1 创建变量2.2 数据绑定 3 显示菜品总结 我们上一篇介绍了数据源的设计方法&#xff0c;讲解了菜品分类和菜品数据源的创建以及后台功能的开发。有了后台功能并且准备好数据之后&#xff0c;我们就需要开发小程序部分。 现实中你看到的想到的绝…

大数据电商数仓项目--实战(一)数据准备

第一章 数仓分层 1.1 为什么要分层 1.2 数仓命名规范 1.2.1 表命名 ODS层命名为ods_表名DIM层命名为dim_表名DWD层命名为dwd_表名DWS层命名为dws_表名DWT层命名为dwt_表名ADS层命名为ads_表名临时表命名为tmp_表名 1.2.2 表字段类型 数量类型为bigint金额类型为decimal(16…

电脑usb接口封禁如何实现?5种禁用USB接口的方法分享!(第一种你GET了吗?)

“防患于未然&#xff0c;安全始于细节。”在信息技术飞速发展的今天&#xff0c;企业的信息安全问题日益凸显。 USB接口作为数据传输的重要通道&#xff0c;在带来便利的同时&#xff0c;也成为了数据泄露和安全风险的高发地。 因此&#xff0c;对电脑USB接口进行封闭管理&a…

微服务的优点及在云原生时代的合理落地方式

云计算de小白 那么&#xff0c;微服务到底能给业务带来什么好处&#xff1f;在云原生时代&#xff0c;如何更合理地实现微服务&#xff1f; 架构没有好坏之分&#xff0c;只有适合与不适合。然而&#xff0c;当我们对比微服务架构与单体架构时&#xff0c;可以发现微服务有以…

8--苍穹外卖-SpringBoot项目中套餐管理 详解(二)

目录 删除套餐 需求分析和设计 代码开发 根据id查询套餐 mapper层 Service层 ServiceImpl层 Mapper层 批量删除套餐 mapper层 Service层 ServiceImpl层 Mapper层 SetmealMapper.xml 修改套餐 需求分析和设计 代码开发 起售停售套餐 需求分析和设计 代码开发…

Docker全家桶:从0到加载本地项目

安装docker&#xff0c;我们选择的是CentenOS 7。 目录 Docker安装 命令 命令别名 数据卷挂载 Dockerfile 容器网络互联 Docker安装 1. 先删除本机旧的或者残留的docker sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest …

前端——js基础

一、JavaScript &#xff08;简称js&#xff09;——js可以给网页实现一个动态效果 1.JavaScript 组成 - 核心语法 ECMScipt 简称(es): 规范js的基本语法 1.es是js的语法规范 管理者 2.js是es的实现 操作者 - DOM > 文档对象 提供js操作 (例如…