RDB 持久化详解

article/2025/8/29 17:31:30

文章目录

  • 持久化的执行
    • SAVE:阻塞服务器并创建RDB文件
    • BGSAVE:以非阻塞方式创建RDB文件
    • 通过配置文件自动创建RDB文件
    • 查看最近持久化时间
  • RDB优化配置
    • 1. save
    • 2. stop-write-on-bgsave-error
    • 3. rdbcompression
    • 4. rdbchecksum
    • 5. sanitize-dump-payload
    • 6. dbfilename
    • 7. rdb-del-sync-files
    • 8. dir
  • RDB文件结构
    • 1. 头部信息区
    • 2. 数据区
    • 3. 尾信息区
  • RDB持久化过程
      • Fork 子进程的作用
  • 数据丢失情况分析
    • save 命令数据丢失
    • bgsave 命令数据丢失
  • RDB的优缺点

Redis 是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将 Redis 中的数据以某种形式(数据或命令)从内存保存到硬盘。当下次 Redis 重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。Redis 的持久化机制有两种:

  • RDB(Redis Data Base) 内存快照

  • AOF(Append Only File) 增量日志

持久化的执行

RDB ( Redis Data Base) 指的是在指定的时间间隔内将内存中的数据集快照写入磁盘,RDB 是内存快照(内存数据的二进制序列化形式)的方式持久化,每次都是从 Redis 中生成一个快照进行数据的全量备份。是Redis默认使用的持久化功能。

SAVE:阻塞服务器并创建RDB文件

通过在 redis-cli 客户端中执行 save 命令可立即进行一次持久化保存。save 命令在执行期间会阻塞 redis-server 进程,直至持久化过程完毕。而在 redis-server 进程阻塞期间,Redis不能处理任何读写请求,无法对外提供服务。

image-20230426201826899

BGSAVE:以非阻塞方式创建RDB文件

通过在 redis-cli 客户端中执行 bgsave 命令可立即进行一次持久化保存。不同于 save 命令的是,正如该命令的名称一样,background save,后台运行 save。bgsave 命令会使服务器进程 redis-server 生成一个子进程,由该子进程负责完成保存过程。在子进程进行保存过程中,不会阻塞 redis-server 进程对客户端读写请求的处理。

image-20230426202100858

需要注意的是由于执行BGSAVE命令需要创建子进程,所以父进程占用的内存数量越大,创建子进程这一操作耗费的时间也会越长,因此Redis服务器在执行BGSAVE命令时,仍然可能会由于创建子进程而被短暂地阻塞。

通过配置文件自动创建RDB文件

自动条件触发的本质仍是 bgsave 命令的执行。只不过是用户通过在配置文件中做相应的设置后,Redis 会根据设置信息自动调用 bgsave 命令执行。

image-20230426203346819

持久化策略按照如下顺序进行:

  1. 如果服务器在60秒之内,对数据库进行了至少10000次修改,则进行持久化。
  2. 如果服务器在300秒之内,对数据库进行了至少100次修改,则进行持久化。
  3. 如果服务器在3600秒(一小时)之内,对数据库进行了至少1次修改,则进行持久化。

查看最近持久化时间

通过 lastsave 命令可以查看最近一次执行持久化的时间,其返回的是一个 Unix 时间戳。

image-20230426202434712

RDB优化配置

RDB 相关的配置在 redis.conf 文件的 SNAPSHOTTING 部分。

image-20230426203833976

1. save

该配置用于设置快照的自动保存触发条件,即 save point,保存点。该触发条件是在指定时间段内发生了指定次数的写操作。如果不启用 RDB 持久化,只需设置 save 的参数为空串即可:save “”。

2. stop-write-on-bgsave-error

image-20230426210913995
  • 翻译:

    然而,如果您已经设置了对Redis服务器持久化的正确监控,您可能需要禁用此功能,以便Redis能够继续正常工作,即使磁盘、权限等出现问题。

  • 解释:

    如果在没有设置持久化正确结果的监控的情况下,启用了RDB且最后一次持久化数据失败(磁盘损坏,权限等原因),Redis就会停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到出故障了。当然,如果 bgsave 命令后来可以正常工作了,Redis将自动允许再次写入。

3. rdbcompression

image-20230426212455452
  • 翻译:

    是否在导出.rdb数据库文件的时候采用LZF压缩字符串和对象? 默认情况下总是设置成‘yes’,因为它几乎总是一场胜利。 如果你想在存储的子进程中节省一些CPU就设置成’no’, 但是这样如果你的kye/value是可压缩的,你得到的数据就会很大。

  • 解释:

    设置为yes时,进行持久化会启用 LZF算法压缩来压缩字符串对象。虽然压缩 RDB 文件会消耗系统资源和CPU,降低性能,但可大幅降低磁盘文件的大小,方便保存到磁盘,加速主从集群中从节点的数据同步。

4. rdbchecksum

image-20230426213734444
  • 翻译:

    从RDB的版本5开始CRC64校验和被放置在文件的末尾。这使格式更能抵抗损坏,但有一定的性能在保存和加载RDB文件时按需付费(约10%),因此您可以禁用它以获得最大性能。
    在禁用校验和的情况下创建的RDB文件的校验和为零,这将告诉加载代码跳过检查。

  • 解释:

    在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

5. sanitize-dump-payload

image-20230426214528962
  • 翻译:

    该配置用于设置在加载 RDB 文件或进行持久化时是否开启对 zipList、listPack 等数据的全面安全检测。该检测可以降低命令处理时发生系统崩溃的可能。其可设置的值有三种选择:

    • no:不检测

    • yes:总是检测

    • clients:只有当客户端连接时检测。排除了加载 RDB 文件与进行持久化时的检测。

    默认值本应该是 clients,但其会影响 Redis 集群的工作,所以默认值为 no,不检测。

6. dbfilename

image-20230426214908793

指定 RDB 文件的默认名称,默认为 dump.rdb。

7. rdb-del-sync-files

image-20230426215139564

主从复制时,是否删除用于同步的从机上的 RDB 文件。默认是 no,不删除。不过需要注意,只有当从机的 RDB 和 AOF 持久化功能都未开启时才生效。

8. dir

image-20230426221020560

设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。

RDB文件结构

rdb 文件整体上可分为三个区域:头信息区、数据区、尾信息区。

image-20230427145637747

1. 头部信息区

  1. 魔数

    以 ascii 码 “REDIS” 开头。用来验证当前文件的格式。类似 java 程序编译后的 class 文件,以 “CAFEBABE” 魔数开头,寓意 java 和 cafe 的千丝万缕的关系。

  2. RDB version

    表示RDB文件的版本。并且高版本 redis 可以 100% 向后兼容加载旧版 rdb 文件。版本信息使用 4 个字节表示。 如:30 30 30 37 转换为 ascii 码 00 00 00 07,代表 rdb version 文件为第 7 版。

  3. AUX metadata

    可以存放多组 key-value,用来表示对应元信息。每一对 key-value,都以0xFA 开头。key 和 value 均采用 rdb 字符串编码方法。

    默认元信息列表:

    • redis-ver:redis 版本信息。
    • redis-bits:输出 rdb 文件机器的位数,64bit 或 32 bit。
    • ctime:rdb 文件创建时间。
    • used-mem:rdb 加载到内存中的内存使用量。

2. 数据区

  1. SELECTDB

    常量的长度为 1 字节。当读入程序遇到这个值的时候, 它知道接下来要读入的将是一个数据库号码。

  2. db_number

    保存着一个数据库号码, 根据号码的大小不同, 这个部分的长度可以是 1 字节、 2 字节或者 5 字B节。 当程序读入 db_number 部分之后, 服务器会调用 SELECT 命令, 根据读入的数据库号码进行数据库切换, 使得之后读入的键值对可以载入到正确的数据库中。

  3. key_value_pairs

    保存了数据库中的所有键值对数据。

    不带过期时间的键值对:

    • TYPE 记录了 value 的类型, 长度为 1 字节, 值可以是以下常量的其中一个:

      • REDIS_RDB_TYPE_STRING
      • REDIS_RDB_TYPE_LIST
      • REDIS_RDB_TYPE_SET
      • REDIS_RDB_TYPE_ZSET
      • REDIS_RDB_TYPE_HASH
      • REDIS_RDB_TYPE_LIST_ZIPLIST
      • REDIS_RDB_TYPE_SET_INTSET
      • REDIS_RDB_TYPE_ZSET_ZIPLIST
      • REDIS_RDB_TYPE_HASH_ZIPLIST

      以上列出的每个 TYPE 常量都代表了一种对象类型或者底层编码, 当服务器读入 RDB 文件中的键值对数据时, 程序会根据 TYPE 的值来决定如何读入和解释 value 的数据。

    • key 总是一个字符串对象, 它的编码方式和 REDIS_RDB_TYPE_STRING 类型的 value 一样。 根据内容长度的不同, key 的长度也会有所不同。

    • value会根据 TYPE 类型的不同, 以及保存内容长度的不同, 保存 value 的结构和长度也会有所不同。

    带有过期时间的键值对:

    • EXPIRETIME_MS 常量的长度为 1 字节, 它告知读入程序, 接下来要读入的将是一个以毫秒为单位的过期时间。
    • ms 是一个 8 字节长的带符号整数, 记录着一个以毫秒为单位的 UNIX 时间戳, 这个时间戳就是键值对的过期时间。
    • 带有过期时间的键值对中的 TYPE 、 key 、 value 三个部分的意义, 和前面介绍的不带过期时间的键值对的 TYPE 、 key 、 value 三个部分的意义完全相同。

3. 尾信息区

该区域最为简单。固定使用 9 byte。第一 byte 为 0xFF ,之后固定跟着 8 byte 用于 crc64 校验。该校验码采用crc-64-jones算法生成,用于校验 rdb 文件的合法性。

RDB持久化过程

RDB 持久化方案进行备份时,Redis 会单独 fork 一个子进程来进行持久化,会将数据写入一个临时文件中,持久化完成后替换旧的 RDB 文件。在整个持久化过程中,主进程(为客户端提供服务的进程)不参与 IO 操作,这样能确保 Redis 服务的高性能,RDB 持久化机制适合对数据完整性要求不高但追求高效恢复的使用场景。下面展示 RDB 持久化流程:

关键执行步骤如下

  1. Redis 父进程首先判断:当前是否在执行 save,或 bgsave/bgrewriteaof 的子进程,如果在执行则 bgsave 命令直接返回。bgsave/bgrewriteaof 的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。

  2. 父进程执行 fork 操作创建子进程,这个过程中父进程是阻塞的,Redis 不能执行来自客户端的任何命令。父进程 fork 后,bgsave 命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。

  3. 子进程进程对内存数据生成快照文件。

  4. 父进程在此期间接收的新的写操作,使用 COW 机制写入。

  5. 子进程完成快照写入,替换旧 RDB 文件,随后子进程退出。

在生成 RDB 文件的步骤中,在同步到磁盘和持续写入这个过程是如何处理数据不一致的情况呢?生成快照 RDB 文件时是否会对业务产生影响?

Fork 子进程的作用

上面说到了 RDB 持久化过程中,主进程会 fork 一个子进程来负责 RDB 的备份,这里简单介绍一下 fork:

  • Linux 操作系统中的程序,fork 会产生一个和父进程完全相同的子进程。子进程与父进程所有的数据均一致,但是子进程是一个全新的进程,与原进程是父子进程关系。

  • 出于效率考虑,Linux 操作系统中使用 COW(Copy On Write)写时复制机制,fork 子进程一般情况下与父进程共同使用一段物理内存,只有在进程空间中的内存发生修改时,内存空间才会复制一份出来。

在 Redis 中,RDB 持久化就是充分的利用了这项技术,Redis 在持久化时调用 glibc 函数 fork 一个子进程,全权负责持久化工作,这样父进程仍然能继续给客户端提供服务。fork 的子进程初始时与父进程(Redis 的主进程)共享同一块内存;当持久化过程中,客户端的请求对内存中的数据进行修改,此时就会通过 COW (Copy On Write) 机制对数据段页面进行分离,也就是复制一块内存出来给主进程去修改。

图片

数据丢失情况分析

save 命令数据丢失

时间事件
T0服务器开始运行
T1服务器执行SET k1 v1
T2服务器执行SET k2 v2
T3服务器执行SAVE命令,成功创建RDB文件
T4服务器执行SET k3 v3
T5服务器执行SET k4 v4
T6服务器执行SAVE命令,成功创建RDB文件
T7服务器执行SET k5 v5
T8服务器执行SET k6 v6
T9服务器停机
  • 因为服务器最后一次成功执行SAVE命令是在T6,所以服务器创建出的RDB文件将包含键k1至键k4在内的数据,服务器在重启时将使用这个RDB文件进行数据恢复
  • 因为服务器在T6之后创建了键k5和键k6,并在之后出现停机,所以当服务器重启时,键k5、k6的数据将丢失,而键k1至键k4的数据将被恢复。

bgsave 命令数据丢失

时间事件
T0服务器开始运行
T1服务器执行SET k1 v1
T2服务器执行SET k2 v2
T3服务器执行BGSAVE命令,开始创建RDB文件
T4服务器执行SET k3 v3
T5RDB文件创建完毕
T6服务器执行SET k4 v4
T7服务器执行BGSAVE命令,开始创建RDB文件
T8服务器执行SET k5 v5
T9服务器执行SET k6 v6
T10服务器停机
  • 因为T7创建的新RDB文件尚未完成,所以服务器在停机之后将使用T5成功创建的RDB文件进行数据恢复。
  • 虽然服务器现有的RDB文件是在T5成功创建的,但由于这个文件是在T3开始创建的,所以它只包含了T3之前的数据,即键k1和键k2的数据。
  • 基于上述原因,当服务器重启时,只有键k1和键k2的数据会被恢复,而键k3至键k6的数据则会丢失。

RDB的优缺点

优点

  • 存储紧凑,节省内存空间。

  • 恢复速度非常快。

  • 适合全量备份、全量复制的场景,经常用于灾难恢复(对数据的完整性和一致性要求相对较低的场合)。

缺点

  • 容易丢失数据,容易丢失两次快照之间 Redis 服务器中变化的数据。
  • RDB 通过 fork 子进程对内存快照进行全量备份,是一个重量级操作,频繁执行成本高。
图片

http://chatgpt.dhexx.cn/article/YN0Ax3nH.shtml

相关文章

RDB持久化

RDB持久化 一、RDB快照实现二、快照用法三、执行快照时的数据修改四、RDB 和 AOF 合体 一、RDB快照实现 Redis 是内存数据库,但是它为数据的持久化提供了两个技术。 分别是「 AOF 日志和 RDB 快照」。 这两种技术都会用各用一个日志文件来记录信息,但…

RDB底层原理

Redis服务器自动保存功能的实现原理及文件中的各个组成部分 因为Redis是内存数据库,它将自己的数据库状态储存在内存里 面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面, 那么一旦服务器进程退出,服务器中的数据库…

Redis持久化原理(RDB)

在上一篇文章中,介绍了Redis的内存模型很重要,从这篇文章开始,将依次介绍Redis高可用相关的知识——持久化、复制(及读写分离)、哨兵、以及集群。 本文将先说明上述几种技术分别解决了Redis高可用的什么问题;然后详细介绍Redis的…

运行程序时出现 应用程序无法启动,因为应用程序的并行配置不正确

最近发布给客户的程序中,双击exe程序出现“应用程序无法启动,因为应用程序的并行配置不正确”,下面提示使用sxstrace跟踪调试应用程序运行时需要的动态库的版本和路径。 于是有以下操作: 步骤: 1.利用管理员身份运行命…

谷歌浏览器出现应用程序无法启动,因为应用程序的并行配置不正确....(亲测完美解决)

电脑开机 完整报错提示为: 应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件日志,或使用命令行 sxstrace.exe 工具。 刚开始也在网上找了N久的解决方案(如:启动windws Mod…

成功解决“tesseral应用程序无法打开,因为运行程序并行配置不正确”

目前网上流传的两种方法1是启动Windows Modules Installer并重启 但我的并没有处于禁用状态。 第二种是查看日志安装对应库,比较麻烦。 无意中发现第三种方式,操作更为简单。 我的tesseral版本是7.0.6,初次打开会提示如题报错,…

chrome 应用程序无法启动,因为应用程序的并行配置不正确

方法一: 开始 - 运行(输入services.msc)- 确定或回车,打开:服务(本地); 我们在服务(本地)窗口找到:Windows Modules Installer服务&#…

exe应用程序无法启动,因为应用程序的并行配置不正确

问题:exe应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件日志,或使用命令行 sxstrace.exe 工具。 原因查找: 1)开始→所有程序→附件→右键命令提示符→以管理员身份运…

STM32CubeMx开发之路—在线升级OTA

文章目录 运行环境简介基础知识(1/4)STM32中的程序在哪儿?进行分区总体流程图 BootLoader程序流程图分析程序编写和分析 App程序流程图分析程序编写和分析Ymodem协议代码分析 结果验证代码的下载BootLoader的下载App1的下载生成App2的.bin文件使用Xshell进行文件传输 总结源代…

基于FPGA的在线升级

基于FPGA的在线升级 在线升级的意义在线升级的策略整体框架总结参考文献结束语 在线升级的意义 首先什么是FPGA的在线升级? 所谓FPGA的在线升级其实就是不对FPGA进行常规意义下的下载程序,便可以通过一些手段更新FPGA中的程序,一般用到的工具…

MCU通过UART实现OTA在线升级流程

关注星标公众号,不错过精彩内容 素材来源 | 网络 OTA升级已经不是什么新鲜事,现在大多数物联网终端设备,基本具备这个功能。 今天以AT32为例给大家分享一下OTA升级的详细流程。 概述 空中下载技术OTA(Over-the-Air Technology&…

Qt 在线升级功能

开源QSimpleUpdater是一个Qt在线升级模块 ,但是QSimpleUpdater 由于使用了很久以前的版本,并且近几年没有维护,因此其内部好多Qt的widget文件,这些QWidget与项目的整体风格不符合,说白了就是很丑,现在用QML…

stm32-IAP(在线升级程序)

第一章 背景知识 什么是IAP? IAP的知识网上的各种资料也说的比较明白,在此简单介绍一下。IAP( In Application Programming)即在线应用编程,也就是用户可以使用自己的程序对单片机的User Flash的某一区域&#xff08…

【Android】轻松实现 APK 在线升级

【Android】轻松实现 APK 在线升级 APK 在线升级 APK 在线升级几乎是所有程序必备的功能。 在线升级功能能解决已有的问题并提供更丰富的新功能。 基本的流程是: 检测到新版本信息弹出升级提示窗口点击 No 不进行升级,完毕!点击 Yes 后台…

车载Linux固件升级,一种车载系统固件在线升级方法与流程

本发明涉及汽车系统升级技术领域,尤其涉及一种车载系统固件在线升级方法。 背景技术: 随着汽车智能化、网联化的发展趋势,车联网的技术进步带来汽车软件系统的复杂度不断增加,升级迭代的速度越来越快,软件的不稳定性风险不可避免。统计数据显示,当前市场一半以上的汽车召…

51单片机IAP在线升级

51单片机IAP在线升级 爱矽半导体E85F3325单片机IAP在线升级教程,此处可查看更新及demo下载 文章目录 前言一、ROM资源二、KEIL有关知识1.BL51连接器:2.LX51连接器: 三、Keil其他相关项说明:四、MCU启动文件说明:五、例…

在线升级版本:ESXI6.5升级7.0

将一台使用ESXI6.7的虚升级条件 1、首先确保硬件是否能升级到7.0版本,注意:物理网卡驱动为e1000e不能升级,如果是igbn,则可以顺利升级。拟机升级到了7.0版本。 升级方法 升级方法有补丁升级、在线升级和U盘升级三种方式&#xff0…

Ubuntu 如何 在线升级系统

Ubuntu 如何升级更新系统 有也常用 Kali Linux 的小伙伴会很熟悉,在Kali中我们只需要使用apt/apt-get包管理器执行如下命令即可: sudo apt update && apt upgrade -y一般执行结束就已完成Kali系统的更新或者再加上: sudo apt dist-upgrade -y&am…

跨平台应用开发进阶(三): uni-app 实现资源在线升级/热更新

文章目录 一、前言1.1 Android升级检测机制 二、wgt 资源升级包升级2.1 修改版本号2.2 发行2.3 安装资源升级包2.3.1 代码示例2.3.2 小结 三、整包升级3.1 客户端实现3.2 数据表实现3.3 服务端实现3.4 发版配置3.5 注意事项 四、Uni-app 版本升级中心4.1 升级中心 uni-upgrade-…

STM32 IAP 在线升级原理全解析

点击左上角的“关注”,定期更新 STM32 最新资讯,总有你想要的信息! STM32 IAP 在线升级原理全解析 1. 什么是 IAP? IAP(In-Application Programming)是用户自己的程序在运行过程中对 User Flash 部分的区域…