Redis持久化 | RDB AOF | 常见问题

news2025/7/18 17:50:23

目录

RDB(Redis DataBase)

给什么内存数据做快照——(全量)

触发机制

RDB文件生成的时候会阻塞主线程吗?

关闭持久化命令

bgsave执行流程

RDB文件怎么配置?有哪些优缺点

优点:

缺点:

问题——数据丢失!

AOF(append only file)

使用方法

AOF工作流程

命令写入

AOF为什么选择直接采用文本协议方式?

AOF为什么将AOF命令要追加到缓冲中【aof_buf】?

AOF缓存同步文件策略有哪些?

怎么选择这些同步文件的策略呢?

重写机制 rewrite

为什么重写后的AOF文件会变小?

重写的时机?

好处:降低空间 & 体量小的AOF文件在redis中加载快。

PS:如果在Redis在进行AOF重写时,有写入操作,这个操作也会被写到重写日志的缓冲区。这样,重写日志也不会丢失最新的操作。

重启加载 load

如果文件损坏,那咋办?

RDB-AOF混合持久化

杂项问题

主线程、子进程和后台线程的联系与区别?

Redis持久化过程中有没有其他潜在的阻塞风险?

如何改善fork操作的耗时问题?

为什么主从库间的复制不使用 AOF?


Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。

RDB(Redis DataBase)

RDB持久化是把当前进程数据生成快照保存到硬盘的过程。所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。

有这样几个问题:

  1. 给什么内存数据做快照——(全量)

Redis 的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中。但是,RDB 文件就越大,往磁盘上写数据的时间开销就越大。

  1. 触发机制

除了手动触发RDB文件生成命令,自动触发RDB持久化机制。

  • save m n ——表示m秒内对数据集存在n次修改,自动触发bgsave

  • 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。

  • 执行debug reload命令重新加载Redis 时,也会自动触发save操作。

  • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

  1. RDB文件生成的时候会阻塞主线程吗?

  • save【线上环境不推荐】:在主线程中执行,会导致阻塞。对于内存比较大的实例会造成长时间阻塞。

  • bgsave【推荐】:为了快照而暂停写操作,肯定是不能接受的。所以这个时候,Redis 就会借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。

  1. 关闭持久化命令

    save ""

  2. bgsave执行流程

bgsave子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。如果主线程对这些数据也都是读操作(例如图中的键值对 A),那么,主线程和bgsave 子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对 B),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

  1. RDB文件怎么配置?有哪些优缺点

dbfilename配置进行指定,可以通过执行config set dir {newDir}和config set dbfilename (newFileName}运行期动态执行,当下次运行时RDB文件会保存到新目录。

【推荐】Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression { yes |no}动态修改。虽然压缩RDB会消耗CPU,但可大幅降低文件的体积,方便保存到硬盘或通过网络发送给从节点。

如果 Redis加载损坏的RDB文件时拒绝启动,并打印如下日志:Short read or OOM loading DB. Unrecoverable error,aborting now.可以使用Redis提供的redis-check-rdb工具(老版本是redis-check-dump)检测RDB文件并获取对应的错误报告。

优点:

RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。

比如每隔几小时执行bgsave备份,并把 RDB文件拷贝到远程机器或者文件系统中(如hdfs),,用于灾难恢复。

Redis加载RDB恢复数据远远快于AOF的方式。

缺点:

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

  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

  1. 问题——数据丢失!

我们先在 T0 时刻做了一次快照(下一次快照是T4时刻),然后在T1时刻,数据块 5 和 8 被修改了。如果在T2时刻,机器宕机了,那么,只能按照 T0 时刻的快照进行恢复。此时,数据块 5 和 8 的修改值因为没有快照记录,就无法恢复了。

如果想丢失较少的数据,那么T4-T0就要尽可能的小,但是如果频繁地执行全量

快照,也会带来两方面的开销:

  • 频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

  • 另一方面,bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave 子进程,这就会频繁阻塞主线程了。

正因为有这些缺点,为此Redis提出AOF持久化来解决。

AOF(append only file)

使用方法

  • 开启AOF功能需要设置配置:appendonly yes,默认不开启。

  • AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同RDB持久化方式一致,通过dir配置指定。

AOF工作流程

AOF的工作流程主要是4个部分:命令写入( append)、文件同步( sync)、文件重写(rewrite)、重启加载( load)。

命令写入

AOF命令写入的内容直接是RESP文本协议格式。

例如lpush dura A B这条命令,在AOF缓冲区会追加如下文本:

*3\r\n$6\r\nlupush\r\n$5\r\ndura\r\n$3\r\nA B

AOF 日志的内容。其中,“*3”表示当前命令有三个部分,每部分都是“+数字”开头,后面紧跟着

具体的命令、键或值。这里,“数字”表示这部分中的命令、键或值一共有多少字节

如:由“3 set”表示这部分有 3 个字节,也就是“set”命令。

AOF为什么选择直接采用文本协议方式?

文本协议具有很好的兼容性。开启AOF后,所有写入命令都包含追加操作,直接采用协议格式,避免了二次处理开销。文本协议具有可读性,方便直接修改和处理。

AOF为什么将AOF命令要追加到缓冲中【aof_buf】?

Redis使用单线程响应命令,如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡。

AOF缓存同步文件策略有哪些?

配置参数appendfsync

其中有三种可选择的选项

  • always:同步写回,每个写命令执行完,立马同步地将日志写回磁盘。

  • everysec:每秒写回,每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘。

  • no:操作系统控制的写回,每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘,通常同步周期最长30秒。

怎么选择这些同步文件的策略呢?

【不推荐】配置为always时,每次写入都要同步AOF文件,在一般的SATA 硬盘上,Redis只能支持大约几百TPS写入,显然跟Redis高性能特性背道而驰,不建议配置。

配置为no,由于操作系统每次同步AOF文件的周期不可控,而且会加大每次同步硬盘的数据量,虽然提升了性能,但数据安全性无法保证。

配置为everysec,是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据。(严格来说最多丢失1秒数据是不准确的)

  • 高性能,就选择 no 策略。

  • 如果想要得到高可靠性保证,就选择always 策略。

  • 如果允许数据有一点丢失,又希望性能别受太大影响的话,那么就选择everysec 策略。

重写机制 rewrite

随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

为什么重写后的AOF文件会变小?
  • 进程内已经超时的数据不再写入文件。

  • 旧的AOF文件含有无效命令,重写使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令。

  • 多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为: lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset等类型操作,以64个元素为界拆分为多条。

重写的时机?
  • 手动触发:bgrewriteaof

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

    • auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB。

    • auto-aof-rewrite-percentage :代表当前AOF 文件空间(aof_currentsize)和上一次重写后AOF 文件空间(aof_base_size)的比值。

好处:降低空间 & 体量小的AOF文件在redis中加载快。
PS:如果在Redis在进行AOF重写时,有写入操作,这个操作也会被写到重写日志的缓冲区。这样,重写日志也不会丢失最新的操作。

重启加载 load

AOF和 RDB 文件都可以用于服务器重启时的数据恢复。

  • 当AOF和RDB文件同时存在时,先加载AOF

  • 如果关闭了AOF,就加载RDB

  • 加载成功的情况下,Redis重启成功

  • AOF/RDB存在错误,会打印错误信息。

如果文件损坏,那咋办?

加载损坏的AOF 文件时会拒绝启动,对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof --fix命令进行修复,对比数据的差异,找出丢失的数据,有些可以人工修改补全。

AOF文件可能存在结尾不完整的情况,比如机器突然掉电导致AOF尾部文件命令写入不全。Redis为我们提供了aof-load-truncated 配置来兼容这种情况,默认开启。加载AOF时当遇到此问题时会忽略并继续启动,同时如下警告日志。

RDB-AOF混合持久化

aof-use-rdb-preamble 打开混合开关。

该状态开启后,如果执行bgrewriteaof命令,则会把当前内存中已有的数据弄成二进程存放在aof文件中,这个过程模拟了RDB生成的过程,然后Redis后面有其他命令,在触发下次重写之前,依然采用AOF追加的方式

杂项问题

主线程、子进程和后台线程的联系与区别?

  • 进程和线程的区别

从操作系统的角度来看,进程一般是指资源分配单元,例如一个进程拥有自己的堆、栈、虚存空间(页表)、文件描述符等;而线程一般是指 CPU 进行调度和执行的实体。一个进程启动后,没有再创建额外的线程,那么,这样的进程一般称为主进程或主线程。

Redis 启动以后,本身就是一个进程,它会接收客户端发送的请求,并处理读写操作请求。而且,接收请求和处理请求操作是 Redis 的主要工作,Redis 没有再依赖于其他线程,所以,一般把完成这个主要工作的 Redis 进程,称为主进程或主线程。

  • 主线程与子进程

通过fork创建的子进程,一般和主线程会共用同一片内存区域,所以就需要使用到写时复制技术确保安全。

  • 后台线程

从 4.0 版本开始,Redis 也开始使用pthread_create 创建线程,这些线程在创建后,一般会自行执行一些任务,例如执行异步删除任务

Redis持久化过程中有没有其他潜在的阻塞风险?

当Redis做RDB或AOF重写时,一个必不可少的操作就是执行fork操作创建子进程,对于大多数操作系统来说fork是个重量级错误。虽然fork创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。例如对于10GB的Redis进程,需要复制大约20MB的内存页表,因此fork操作耗时跟进程总内存量息息相关,如果使用虚拟化技术,特别是Xen虚拟机,fork操作会更耗时。

Info status

对于高流量的Redis实例OPS可达5万以上,如果fork操作耗时在秒级别将拖慢Redis几万条命令执行,对线上应用延迟影响非常明显。正常情况下fork耗时应该是每GB消耗20毫秒左右。可以在info stats统计中查latest_fork_usec指标获取最近一次fork操作耗时,单位微秒。

如何改善fork操作的耗时问题?

  • 优先使用物理机或者高效支持fork操作的虚拟化技术

  • 控制Redis实例最大可用内存,fork耗时跟内存量成正比,线上建议每个Redis实例内存控制在10GB 以内。

  • 降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等。

为什么主从库间的复制不使用 AOF?

  • RDB 文件是二进制文件,无论是要把 RDB 写入磁盘,还是要通过网络传输 RDB,IO效率都比记录和传输 AOF 的高。

  • 在从库端进行恢复时,用 RDB 的恢复效率要高于用 AOF。

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

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

相关文章

React 列表渲染

开发环境:Reacttsantd 你可能经常需要通过 JavaScript 的数组方法 来操作数组中的数据,从而将一个数据集渲染成多个相似的组件。在这篇文章中,你将学会如何在 React 中使用 filter() 筛选需要渲染的组件和使用 map() 把数组转换成组件数组。 …

[ctfshow web入门] web25

信息收集 要想拿到flag,需要突破两层if。 解题 第一个if 传入r0,拿到mt_rand的值,由于每一次访问都会重新设置种子,所以每一次访问都是一样的随机数。 所以我们的r mt_rand-显示的值 1799250188 r1799250188就可以突破第一…

【数据结构】树的介绍

目录 一、树1.1什么是树?1.2 树的概念与结构1.3树的相关术语1.4 树形结构实际运用场景 二、二叉树2.1 概念与结构2.2 特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 个人主页,点击这里~ 数据结构专栏,点击这里~ 一、树 1.1什么是树&#xff1…

Android源码之App启动

目录 App启动概述 App启动过程 App启动过程图 源码概述 跨进程启动 进程内启动 下面以应用桌面Launcher启动App的MainActivity来举例: App启动概述 首先,MainActivity是由Launcher组件来启动的,而Launcher又是通过Activity管理服务Act…

【GESP】C++二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S

GESP二级练习,多层循环分支练习,难度★✮☆☆☆。 题目题解详见:https://www.coderli.com/gesp-2-luogu-b3721/ 【GESP】C二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S | OneCoderGESP二级练习,多层循环分支练习&am…

2. Qt界面文件原理

本节主要介绍ui文件如何与窗口关联,并通过隐式连接方式显示对话框 本文部分ppt、视频截图原链接:[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1 UI文件如何与窗口关联 1.1 mainwindow.cpp的头文件ui_mainwindow.h 根据编译原理的基本规…

Elastic 的 OpenTelemetry 分发版(EDOT)现已正式发布:开源、可用于生产环境的 OTel

作者:来自 Elastic Miguel Luna 及 Bahubali Shetti Elastic 自豪地宣布正式发布 Elastic OpenTelemetry 分发版(Elastic Distributions of OpenTelemetry - EDOT),其中包含 Elastic 自定义版本的 OpenTelemetry Collector 以及多…

docker部署jenkins并成功自动化部署微服务

一、环境版本清单: docker 26.1.4JDK 17.0.28Mysql 8.0.27Redis 6.0.5nacos 2.5.1maven 3.8.8jenkins 2.492.2 二、服务架构:有gateway,archives,system这三个服务 三、部署步骤 四、安装linux 五、在linux上安装redis&#…

【NLP 53、投机采样加速推理】

目录 一、投机采样 二、投机采样改进:美杜莎模型 流程 改进 三、Deepseek的投机采样 流程 Ⅰ、输入文本预处理 Ⅱ、引导模型预测 Ⅲ、候选集筛选(可选) Ⅳ、主模型验证 Ⅴ、生成输出与循环 骗你的,其实我在意透了 —— 25.4.4 一、…

VScode连接CentOS 7.6虚拟机

本文内容:在Windows上使用VMware运行虚拟机,然后使用VScode连接CentOS 7.6虚拟机。 进入系统前 安装VMware 安装教程参考:VMware安装 下载CentOS 7.6镜像 可以使用国内镜像源,但是一般国内镜像源要么已经不维护CentOS 7.6这个…

高德地图 3D 渲染-区域纹理图添加

引入-初始化地图&#xff08;关键代码&#xff09; // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…

搭建hadoop集群模式并运行

3.1 Hadoop的运行模式 先去官方看一看Apache Hadoop 3.3.6 – Hadoop: Setting up a Single Node Cluster. 本地模式&#xff1a;数据直接存放在Linux的磁盘上&#xff0c;测试时偶尔用一下 伪分布式&#xff1a;数据存放在HDFS&#xff0c;公司资金不足的时候用 完全分布式&a…

Qt实现鼠标右键弹出弹窗退出

Qt鼠标右键弹出弹窗退出 1、鼠标右键实现1.1 重写鼠标点击事件1.2 添加头文件1.3 添加定义2、添加菜单2.1添加菜单头文件2.2创建菜单对象2.3 显示菜单 3、添加动作3.1添加动作资源文件3.2 添加头文件3.3 创建退出动作对象3.4菜单添加动作对象 4、在当前鼠标位置显示菜单4.1当前…

Springboot整合Mybatis+Maven+Thymeleaf学生成绩管理系统

前言 该系统为学生成绩管理系统&#xff0c;可以当作学习参考&#xff0c;也可以成为Spirng Boot初学者的学习代码&#xff01; 系统描述 学生成绩管理系统提供了三种角色&#xff1a;学生&#xff0c;老师&#xff0c;网站管理员。主要实现的功能如下&#xff1a; 登录 &a…

C#里第一个WPF程序

WPF程序对界面进行优化,但是比WINFORMS的程序要复杂很多, 并且界面UI基本上不适合拖放,所以需要比较多的时间来布局界面, 产且需要开发人员编写更多的代码。 即使如此,在面对诱人的界面表现, 随着客户对界面的需求提高,还是需要采用这样的方式来实现。 界面的样式采…

PyTorch 生态迎来新成员:SGLang 高效推理引擎解析

SGLang 现已正式融入 PyTorch 生态系统&#xff01;此次集成确保了 SGLang 符合 PyTorch 的技术标准与最佳实践&#xff0c;为开发者提供了一个可靠且社区支持的框架&#xff0c;助力大规模语言模型&#xff08;LLM&#xff09;实现高效且灵活的推理。 如需深入了解 PyTorch…

时序数据库 TDengine Cloud 私有连接实战指南:4步实现数据安全传输与成本优化

小T导读&#xff1a;在物联网和工业互联网场景下&#xff0c;企业对高并发、低延迟的数据处理需求愈发迫切。本文将带你深入了解 TDengineCloud 如何通过全托管服务与私有连接&#xff0c;帮助企业实现更安全、更高效、更低成本的数据采集与传输&#xff0c;从架构解析到实际配…

微服务注册中心选择指南:Eureka vs Consul vs Zookeeper vs Nacos

文章目录 引言微服务注册中心概述什么是服务注册与发现选择注册中心的标准 常见的微服务注册中心1. Eureka1.1 理论基础1.2 特点1.3 示例代码 2. Consul2.1 理论基础2.2 特点2.3 示例代码 3. Zookeeper3.1 理论基础3.2 特点3.3 示例代码 4. Nacos4.1 理论基础4.2 特点4.3 示例代…

厦门未来之音:科技与自然共舞的奇幻篇章

故事背景 故事发生在中国福建厦门&#xff0c;描绘未来城市中科技与传统文化深度融合的奇景。通过六大创新场景展现人与自然、历史与未来的和谐共生&#xff0c;市民在智能设施中感受文化传承的力量。 故事内容 从鼓浪屿的声波音乐栈道到BRT天桥上的空中茶园&#xff0c;从修复…