一文搞懂 Redis 的 RDB 持久化技术,大厂开发必备
mhr18 2025-05-10 23:25 15 浏览 0 评论
在互联网大厂后端开发领域,Redis 凭借其高性能、高并发的特点,成为了众多项目中不可或缺的数据存储工具。无论是缓存热点数据,还是处理实时计数器,Redis 都能轻松应对。然而,Redis 作为内存数据库,一旦服务器断电、重启等情况发生,内存中的数据就会丢失。为了保证数据的安全性和可靠性,数据持久化就显得尤为重要。而 RDB(Redis Database)作为 Redis 提供的两种持久化方式之一,在很多场景下都发挥着关键作用。
RDB 究竟是什么?
RDB 持久化是把当前进程数据生成快照保存到磁盘上的过程 ,它将数据库在某一时刻的状态以二进制文件的形式进行全量备份到磁盘,记录的是某一时刻的全量数据,这就好比给数据库拍了一张照片,把当时的所有数据都定格保存下来,这个快照文件就称为 RDB 文件。
RDB 的触发机制
RDB 的触发机制分为手动触发和自动触发这两大类别。
手动触发
save 命令:此命令会阻塞当前 Redis 服务器,直至 RDB 过程完全结束。在高并发的线上环境中,倘若 Redis 内存数据量庞大,save 命令的执行会造成长时间的阻塞,导致 Redis 无法及时处理客户端的请求,极大地影响用户体验,因此在生产环境中一般不建议使用。例如,当 Redis 服务器处理大量的实时交易数据缓存时,若执行 save 命令,可能会使得新的交易请求无法及时响应,造成交易延迟甚至失败。
bgsave 命令:当客户端发送 bgsave 命令后,Redis 会调用 fork 函数创建一个子进程。该子进程专门负责将数据写入临时文件,完成写入操作后,再用临时文件原子替换上次持久化好的文件。在此期间,父进程(即主进程)能够继续处理客户端的命令请求,不会被阻塞。不过,需要注意的是,主进程其实会短暂阻塞在 fork () 过程中,只是在通常情况下,该指令的执行速度相对较快,对整体性能的影响较为有限。比如在一个电商秒杀场景中,大量用户同时请求 Redis 缓存中的商品库存数据,此时若使用 bgsave 命令进行 RDB 持久化,主进程仍可高效处理这些高并发请求,而子进程在后台完成数据持久化工作,互不干扰。
自动触发
存在以下几种自动触发 bgsave 命令生成 rdb 文件的情况:
save m n 配置触发:在 redis.conf 配置文件中,可以设置 save m n 参数,其含义是在 m 秒内,若数据库发生了至少 n 次修改操作,就会自动触发 bgsave 操作。例如,常见的默认配置有 “save 900 1”,这表示如果在 900 秒内,数据库中有至少 1 条数据发生了修改,就会自动执行 bgsave 来生成 RDB 文件;“save 300 10” 意味着 300 秒内若有至少 10 次数据修改,也会触发;还有 “save 60 10000”,即 60 秒内出现至少 10000 次数据修改时触发。这种配置方式能够根据业务数据的变化频率,灵活地进行 RDB 持久化操作,在数据变动达到一定程度时,及时保存数据状态。
主从复制触发:在 Redis 的主从复制架构中,当从节点需要从主节点进行全量复制时,会触发主节点执行 bgsave 操作。主节点生成当前时刻的快照,并将其发送给从节点,以完成从节点的数据初始化。例如,在一个分布式系统中,新增了一个从节点来分担读压力,此时主节点就会自动触发 bgsave,将自身的数据状态快照传递给新的从节点,确保从节点与主节点的数据一致性。
debug reload 命令触发:当执行 debug reload 命令重新加载 Redis 时,也会触发 bgsave 操作,以便重新加载配置的同时,保存当前的数据状态。这在运维人员对 Redis 进行配置调整并希望保留当前数据状态时非常有用。
shutdown 命令触发:在默认情况下,当执行 shutdown 命令关闭 Redis 服务且未开启 AOF 持久化时,也会触发 bgsave 操作,将内存中的数据保存到磁盘,防止数据丢失。
RDB 的执行过程
当执行 bgsave 时,其具体执行流程如下:
1、主进程首先会检查当前是否已有正在执行的子进程。若存在正在执行的子进程(例如之前的 bgsave 操作尚未完成,或者正在进行 AOF 重写等其他子进程操作),那么主进程直接返回,不再重复创建子进程,避免资源浪费和可能的冲突。
2、若当前没有正在执行的子进程,主进程则调用 fork 函数创建一个新的子进程。这个 fork 过程会短暂阻塞主进程,在阻塞期间,主进程无法处理客户端请求,但由于 fork 操作通常执行速度较快,对性能的影响一般较小。一旦 fork 完成,主进程即可恢复正常,继续处理客户端的命令请求。
3、新创建的子进程负责执行数据持久化工作。子进程首先将数据写入一个临时的 rdb 文件中。在写入过程中,子进程会按照特定的格式,将 Redis 内存中的数据结构,如键值对、哈希表、列表等,依次转换为二进制形式写入临时文件。当所有数据都成功写入临时 rdb 文件后,子进程会执行原子替换操作,用这个新生成的临时 rdb 文件替换掉旧的 rdb 文件。原子替换操作能够确保在文件替换过程中,不会出现数据不一致或文件损坏的情况,保证了 RDB 文件的完整性。
4、子进程完成数据写入和文件替换后,会发送一个信号给主进程,通知主进程 RDB 持久化操作已经完成。主进程接收到该信号后,会更新相关的统计信息,例如在 info Persitence 下的 rdb_* 相关选项,记录本次 RDB 操作的完成时间、文件大小等信息,方便运维人员进行监控和管理。
写时复制(COW)技术
在 RDB 执行过程中,写时复制(Copy - on - Write,COW)技术发挥着至关重要的作用。其核心原理如下:
Redis 主进程 fork 生成的子进程可以共享主进程的所有内存数据。在 fork 操作完成后的初始阶段,父子进程共享同一块内存空间,并不会立刻对内存进行拷贝,而是将真正的内存拷贝动作推迟到实际需要修改数据的时候。
假设在 RDB 快照期间,主进程和 bgsave 子进程同时访问内存数据。如果主进程只是读取内存数据,那么这与 bgsave 子进程的操作并不冲突,因为读取操作不会改变内存数据的状态,父子进程可以安全地共享该内存数据。
但如果主进程要修改 Redis 内存中的某个数据(例如数据 C),此时操作系统内核会发挥关键作用。操作系统内核会将被修改的内存数据复制一份,这个复制出来的数据是修改之前的原始数据。复制完成后,未被修改的内存数据依然由父子两个进程共享,而被主进程修改的内存空间则归属于主进程,被复制出来的原始数据归属于子进程。、
这样一来,主进程就能够在 RDB 快照发生的过程中,毫无顾虑地接受并处理数据写入的请求,而子进程也仍然能够基于复制时的数据状态,对某一时刻的内存数据做完整的快照,既保证了数据的一致性,又提高了系统在快照期间的并发处理能力。例如,在一个实时数据分析系统中,Redis 缓存着大量的实时数据,在进行 RDB 快照时,主进程可能会不断接收新的数据分析结果并写入 Redis,而借助写时复制技术,子进程可以不受干扰地对当前数据状态进行快照保存,确保数据的完整性和准确性。
RDB 文件特点
RDB 文件具有一些显著的特点:
(一)二进制文件且体积小
RDB 文件采用二进制格式存储数据,这种格式相较于文本格式,能够更紧凑地表示数据,从而大大减小了文件的体积。同时,RDB 文件默认使用 LZF 算法进行压缩,进一步压缩了文件大小。较小的文件体积使得 RDB 文件在备份和传输过程中更加高效,占用更少的网络带宽和磁盘空间。例如,在进行数据异地备份时,较小的 RDB 文件能够更快地传输到远程服务器,减少备份时间和成本。
(二)恢复速度快
在恢复数据时,加载 RDB 文件到内存的速度相对 AOF 方式更快。这是因为 RDB 文件记录的是某一时刻的全量数据,在加载时,Redis 可以直接按照二进制格式快速将数据读入内存,重建数据结构。而 AOF 文件记录的是一系列的写命令,在恢复时需要逐条执行这些命令来重建数据,相对而言耗时更长。所以在一些对数据恢复速度要求极高的场景,如电商大促前的服务器数据恢复、游戏服务器重启后的快速数据加载等,RDB 的恢复速度优势就显得尤为重要。
总结
总结一下,RDB 的优点很明显,文件体积小,便于传输和备份,数据恢复速度快。但它也有缺点,RDB 是间隔性的全量持久化,两次持久化之间如果发生故障,会丢失这期间的数据;而且 bgsave 执行期间,如果数据修改频繁,fork 出来的子进程内存占用会很大。所以,大家在实际项目中,要根据业务场景,合理选择 RDB 持久化方式,也可以结合 AOF,取长补短。欢迎大家在评论区分享自己在 Redis 数据持久化方面的实践经验和遇到的问题,咱们一起探讨!
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)