当前位置: 首页 > news >正文

Redis持久化:RDB与AOF全面解析

Redis 是一个内存数据库,所以其运行效率非常高。但也存在一个问题:内存中的数据是不持久的,若主机宕机或 Redis 关机重启,则内存中的数据全部丢失。当然,这是不允许的。
Redis 具有持久化功能,其会按照设置以快照操作日志的形式将数据持久化到磁盘。
根据持久化使用技术的不同,Redis 的持久化分为两种:RDB AOF

1. 持久化基本原理

Redis 持久化也称为钝化,是指将内存中数据库的状态描述信息保存到磁盘中。只不过是不同的持久化技术,对数据的状态描述信息是不同的,生成的持久化文件也是不同的。但它们的作用都是相同的:避免数据意外丢失。
通过手动方式,或自动定时方式,或自动条件触发方式,将内存中数据库的状态描述信息写入到指定的持久化文件中。当系统重新启动时,自动加载持久化文件,并根据文件中数据库状态描述信息将数据恢复到内存中,这个数据恢复过程也称为激活。这个钝化与激活的过程就是 Redis 持久化的基本原理。
不过从以上分析可知,对于 Redis 单机状态下,无论是手动方式,还是定时方式或条件触发方式,都存在数据丢失问题:在尚未手动/自动保存时发生了 Redis 宕机状况,那么从上次保存到宕机期间产生的数据就会丢失。不同的持久化方式,其数据的丢失率也是不同的。

RDB 是默认持久化方式,但 Redis 允许 RDB AOF 两种持久化技术同时开启,此时系统会使用AOF 方式做持久化,即 AOF 持久化技术的优先级要更高。同样的道理,两种技术同时开启状态下,系统启动时若两种持久化文件同时存在,则优先加载 AOF 持久化文件。

1.1 RDB持久化

RDBRedis DataBase,是指将内存中某一时刻的数据快照全量写入到指定的 rdb 文件的持久化技术。
RDB 持久化默认是开启的。当 Redis 启动时会自动读取 RDB 快照文件,将数据从硬盘载入到内存,以恢复 Redis 关机前的数据库状态。

1.1.1 持久化的执行

RDB 持久化的执行有三种方式:手动 save 命令、手动 bgsave 命令,与自动条件触发。
手动save命令

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

通过在 redis-cli 客户端中执行 bgsave 命令可立即进行一次持久化保存。不同于 save 命令的是,正如该命令的名称一样,background save,后台运行 save
bgsave 命令会使服务器进程 redis-server 生成一个子进程,由该子进程负责完成保存过程。在子进程进行保存过程中,不会阻塞 redis-server 进程对客户端读写请求的处理。
自动条件触发
自动条件触发的本质仍是 bgsave 命令的执行。只不过是用户通过在配置文件中做相应的设置后,Redis 会根据设置信息自动调用 bgsave 命令执行。
查看持久化时间
通过 lastsave 命令可以查看最近一次执行持久化的时间,其返回的是一个 Unix 时间戳。

1.1.2 RDB优化配置

RDB 相关的配置在 redis.conf 文件的 SNAPSHOTTING 部分
save
该配置用于设置快照的自动保存触发条件,即 save point,保存点。该触发条件是在指定时间段内发生了指定次数的写操作。除非另有规定,默认情况下持久化条件为 save 3600 1
300 100 60 10000。其等价于以下三条:
  • save 3600 1        # 在3600 (1 小时)内发生 1 次写操作
  • save 300 100      # 在 300 (5 分钟)内发生 100 次写操作
  • save 60 10000    # 在 60 (1 分钟)内发生 1 万次写操作
如果不启用 RDB 持久化,只需设置 save 的参数为空串即可:save “”
stop-write-on bgsave-error

默认情况下,如果 RDB 快照已启用(至少一个保存点),且最近的 bgsave 命令失败,Redis 将停止接受写入。
这样设置是为了让用户意识到数据没有正确地保存到磁盘上,否则很可能没有人会注意到,并会发生一些灾难。当然,如果 bgsave 命令后来可以正常工作了,Redis 将自动允许再次写入。
rdbcompression

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

RDB5 开始,RDB 文件的 CRC64 校验和就被放置在了文件末尾。这使格式更能抵抗 RDB 文件的损坏,但在保存和加载 RDB 文件时,性能会受到影响(约 10%),因此可以设置为 no 禁用校验和以获得最大性能。
在禁用校验和的情况下创建的 RDB 文件的校验和为零,这将告诉加载代码跳过校验检查。默认为 yes,开启了校验功能。
sanitize-dump-payload

该配置用于设置在加载 RDB 文件或进行持久化时是否开启对 zipListlistPack 等数据的全面安全检测。该检测可以降低命令处理时发生系统崩溃的可能。其可设置的值有三种选择:
  • no:不检测
  • yes:总是检测
  • clients:只有当客户端连接时检测。排除了加载 RDB 文件与进行持久化时的检测。
默认值本应该是 clients,但其会影响 Redis 集群的工作,所以默认值为 no,不检测。
dbfilename

指定 RDB 文件的默认名称,默认为 dump.rdb
rdb-del-sync-files

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

指定 RDB AOF 文件的生成目录。默认为 Redis 安装根目录。

1.1.3 RDB文件结构

RDB 持久化文件 dump.rdb 整体上有五部分构成:

SOF
SOF 是一个常量,一个字符串 REDIS,仅包含这五个字符,其长度为 5。
用于标识 RDB文件的开始,以便在加载 RDB 文件时可以迅速判断出文件是否是 RDB 文件。
rdb_version
个整数,长度为 4 字节,表示 RDB 文件的版本号。
EOF
个常量,占 1 个字节,用于标识 RDB 数据的结束,校验和的开始。
check_sum
校验和 check_sum 用于判断 RDB 文件中的内容是否出现数据异常。其采用的是 CRC 校验算法。
CRC 校验算法:
在持久化时,先将 SOFrdb_version 及内存数据库中的数据快照这三者的二进制数据拼接起来,形成一个二进制数(假设称为数 a),然后再使用这个 a 除以校验和 check_sum,此
时可获取到一个余数 b,然后再将这个 b 拼接到 a 的后面,形成 databases

在加载时,需要先使用 check_sum RDB 文件进行数据损坏验证。验证过程:只需将 RDB 文件中除 EOF check_sum 外的数据除以 check_sum。只要除得的余数不是 0,就说明文件发生损坏。当然,如果余数是 0,也不能肯定文件没有损坏。

这种验证算法,是数据损坏校验,而不是数据没有损坏的校验。
databases

databases部分是RDB文件中最重要的数据部分,其可以包含任意多个非空数据库。每个database由三部分组成:

  • SODB:常量,占1个字节,用于标识一个数据库的开始;
  • db_number:数据库编号
  • key_value_pairs:当前数据库中的键值对数据

1.1.4 RDB持久化过程

对于 Redis 默认的 RDB 持久化,在进行 bgsave 持久化时,redis-server 进程会 fork 出一个bgsave 子进程,由该子进程以异步方式负责完成持久化。而在持久化过程中,redis-server
进程不会阻塞,其会继续接收并处理用户的读写请求。
bgsave 子进程的详细工作原理如下:
  • 由于子进程可以继承父进程的所有资源,且父进程不能拒绝子进程的继承权。所以,bgsave 子进程有权读取到 redis-server 进程写入到内存中的用户数据,使得将内存数据持久化到dump.rdb 成为可能。
  • bgsave 子进程在持久化时首先会将内存中的全量数据 copy 到磁盘中的一个 RDB 临时文件,copy 结束后,再将该文件 rename dump.rdb,替换掉原来的同名文件。

不过,在进行持久化过程中,如果 redis-server 进程接收到了用户写请求,则系统会将内存中发生数据修改的物理块 copy 出一个副本。等内存中的全量数据 copy 结束后,会再将副本中的数据 copy 到 RDB 临时文件。这个副本的生成是由于 Linux 系统的写时复制技术(Copy-On-Write)实现的。

2. AOF持久化

AOFAppend Only File,是指 Redis 将每一次的写操作都以日志的形式记录到一个 AOF 文件中的持久化技术。
当需要恢复内存数据时,将这些写操作重新执行一次,便会恢复到之前的内存数据状态。

只丢失最后一秒或者最后一次写操作的数据。

2.1 AOF基础配置

2.1.1 AOF的开启

默认情况下 AOF 持久化是没有开启的,通过修改配置文件中的 appendonly 属性为 yes 可以开启。

2.1.2 文件名配置

原本只有一个appendonly.aof文件,现在多了三类多个文件:

基本文件:可以是RDF格式也可以是AOF格式,其存放的内容是由RDB转为AOF当时内存的快照数据,该文件可以有多个;

增量文件:以操作日志形式记录转为AOF后的写入操作,该文件可以有多个;

清单文件:用于维护AOF文件的创建顺序,保障激活时的应用顺序。该文件只有一个。

2.1.3 混合式持久化开启

对于基本文件可以是 RDB 格式也可以是 AOF 格式。通过 aof-use-rdb-preamble 属性可以选择。其默认值为 yes,即默认 AOF 持久化的基本文件为 rdb 格式文件,也就是默认采用混合式持久化。

2.1.4 AOF文件目录配置

为了方便管理,可以专门为 AOF 持久化文件指定存放目录。目录名由 appenddirname 属性指定,存放在 redis.conf 配置文件的 dir 属性指定的目录,默认为 Redis 安装目录。

2.2 AOF文件格式

AOF 文件包含三类文件:基本文件、增量文件与清单文件。其中基本文件一般为 rdb 格式

2.1.1 Redis协议(增量文件)

增量文件扩展名为.aof,采用 AOF 格式。AOF 格式其实就是 Redis 通讯协议格式,AOF 持久化文件的本质就是基于 Redis 通讯协议的文本,将命令以纯文本的方式写入到文件中。
Redis 协议规定,Redis 文本是以行来划分,每行以 \r\n 行结束。每一行都有一个消息头,以表示消息类型。消息头由六种不同的符号表示,其意义如下:

2.1.2 查看AOF文件

打开 appendonly.aof.1.incr.aof 文件,可以看到如下格式内容:

2.1.3 清单文件

该文件首先会按照 seq 序号列举出所有基本文件,基本文件 type 类型为 b,然后再按照 seq 序号再列举出所有增量文件,增量文件 type 类型为 i
对于 Redis 启动时的数据恢复,也会按照该文件由上到下依次加载它们中的数据。

2.3 Rewrite机制

随着使用时间的推移,AOF 文件会越来越大。为了防止 AOF 文件由于太大而占用大量的磁盘空间,降低性能,Redis 引入了 Rewrite 机制来对 AOF 文件进行压缩。

2.3.1 何为rewrite

所谓 Rewrite 其实就是对 AOF 文件进行重写整理。当 Rewrite 开启后,主进程 redis-server 创建出一个子进程 bgrewriteaof,由该子进程完成 rewrite 过程。
其首先对现有 aof 文件进行 rewrite 计算,将计算结果写入到一个临时文件,写入完毕后,再 rename 该临时文件为原 aof 文件名,覆盖原有文件。

2.3.2 rewrite计算

rewrite 计算也称为 rewrite 策略。rewrite 计算遵循以下策略:

2.3.3 手动开启rewrite

Rewrite 过程的执行有两种方式。一种是通过 bgrewriteaof 命令手动开启,一种是通过设置条件自动开启。

该命令会使主进程 redis-server 创建出一个子进程 bgrewriteaof,由该子进程完成 rewrite 过程。而在 rewrite 期间,redis-server 仍是可以对外提供读写服务的。

2.3.4 自动开启rewrite

手动方式需要人办干预,所以一般采用自动方式。由于 Rewrite 过程是一个计算过程,需要消耗大量系统资源,会降低系统性能。所以,Rewrite 过程并不是随时随地任意开启的,而是通过设置一些条件,当满足条件后才会启动,以降低对性能的影响。

  • auto-aof-rewrite-percentage:开启 rewrite 的增大比例,默认 100%。指定为 0,表示禁用自动 rewrite
  • auto-aof-rewrite-min-size:开启 rewrite AOF 文件最小值,默认 64M。该值的设置主要是为了防止小 AOF 文件被 rewrite,从而导致性能下降。
自动重写 AOF 文件
AOF 日志文件大小增长到指定的百分比时,Redis 主进程 redis-server 会 fork 出一个子进程 bgrewriteaof 来完成 rewrite 过程。
Redis 会记住最新 rewrite 后的 AOF 文件大小作为基本大小,如果从主机启动后就没有发生过重写,则基本大小就使用启动时 AOF 的大小。
如果当前 AOF 文件大于基本大小的配置文件中指定的百分比阈值,且当前 AOF 文件大于配置文件中指定的最小阈值,则会触发 rewrite

2.4 AOF优化配置

2.4.1 appendfsync(数据同步)

当客户端提交写操作命令后,该命令就会写入到 aof_buf 中,而 aof_buf 中的数据持久化到磁盘 AOF 文件的过程称为数据同步。
何时将 aof_buf 中的数据同步到 AOF 文件?
采用不同的数据同步策略,同时的时机是不同的,有三种策略:
  • always:写操作命令写入 aof_buf 后会立即调用 fsync()系统函数,将其追加到 AOF 文件。该策略效率较低,但相对比较安全,不会丢失太多数据。最多就是刚刚执行过的写操作在尚未同步时出现宕机或重启,将这一操作丢失。
  • no:写操作命令写入 aof_buf 后什么也不做,不会调用 fsync()函数。而将 aof_buf 中的数据同步磁盘的操作由操作系统负责。Linux 系统默认同步周期为 30 秒。效率较高。
  • everysec:默认策略。写操作命令写入 aof_buf 后并不直接调用 fsync(),而是每秒调用一次 fsync()系统函数来完成同步。该策略兼顾到了性能与安全,是一种折中方案。

2.4.2 no-appendfsync-no-rewrite

该属性用于指定,当 AOF fsync 策略设置为 always everysec,当主进程创建了子进程正在执行 bgsave bgrewriteaof 时,主进程是否不调用 fsync()来做数据同步。设置为 no, 双重否定即肯定,主进程会调用 fsync()做同步。而 yes 则不会调用 fsync()做数据同步。
如果调用 fsync(),在需要同步的数据量非常大时,会阻塞主进程对外提供服务,即会存在延迟问题。如果不调用 fsync(),则 AOF fsync 策略相当于设置为了 no,可能会存在 30 秒 数据丢失的风险。

2.4.3 aof-rewrite-incremental-fsync

bgrewriteaof 在执行过程也是先将 rewrite 计算的结果写入到了 aof_rewrite_buf 缓存中,然后当缓存中数据达到一定量后就会调用 fsync()进行刷盘操作,即数据同步,将数据写入到临时文件。

该属性用于控制 fsync()每次刷盘的数据量最大不超过 4MB。这样可以避免由于单次刷盘量过大而引发长时间阻塞。

2.4.4 aof-load-truncated

在进行 AOF 持久化过程中可能会出现系统突然宕机的情况,此时写入到 AOF 文件中的最后一条数据可能会不完整。当主机启动后,Redis AOF 文件不完整的情况下是否可以启动,取决于属性 aof-load-truncated 的设置。其值为:
  • yesAOF 文件最后不完整的数据直接从 AOF 文件中截断删除,不影响 Redis 的启动。
  • noAOF 文件最后不完整的数据不可以被截断删除,Redis 无法启动。

2.4.5 aof-timestamp-enabled

该属性设置为 yes 则会开启在 AOF 文件中增加时间戳的显示功能,可方便按照时间对数据进行恢复。但该方式可能会与 AOF 解析器不兼容,所以默认值为 no,不开启。

2.5 AOF持久化过程

  • 当 Redis 接收到写操作命令时,并不会直接将命令写入磁盘的 AOF 文件,而是先将每一条写命令按照 Redis 通信协议(RESP)格式追加到内存中的 AOF 缓冲区(aof_buf)中。
  • Redis 根据配置的 appendfsync 同步策略(如 everysecalwaysno),在满足同步条件时,将 AOF 缓冲区中的所有数据一次性写入并同步到磁盘的 AOF 文件中,从而减少频繁的磁盘 I/O 操作,提升整体性能。
  • 当 AOF 文件大小达到自动重写的触发条件(如 auto-aof-rewrite-percentageauto-aof-rewrite-min-size)时,Redis 主进程会调用 bgrewriteof 命令并 fork 出一个子进程 bgrewriteaof 来执行 AOF 重写。该子进程会读取当前数据库的最新状态,生成精简化的命令序列,并将这些命令写入一个临时的 AOF 重写文件中。
  • 在重写过程中,主进程继续处理客户端请求,所有新的写命令除了写入原有 AOF 缓冲区外,还会被额外追加到一个专门的 AOF 重写缓冲区(aof_rewrite_buf)中,以确保重写期间的数据不丢失。
  • 当子进程完成对当前数据库状态的重写后,主进程会将 aof_rewrite_buf 中积累的所有写命令追加到该临时文件末尾,确保重写后的文件包含最新的全部数据。
  • 最后,主进程用该临时文件原子地重命名(rename)替换原有的 AOF 文件,完成整个 AOF 重写流程,从而实现 AOF 文件的压缩与优化。

2.6 RDB与AOF对比

持久化方式对比维度详细说明
RDB✅ 文件较小RDB 是定时快照,仅保存某一时刻的数据状态,文件体积小,适合备份和灾难恢复。
✅ 恢复速度快数据以二进制快照形式存储,加载效率高,适用于大规模数据快速重启。
❌ 数据安全性低若在两次快照之间发生宕机,中间写入的数据将丢失,无法保证持久性。
⚠️ 写时复制影响性能使用 fork() 创建子进程,写时复制(COW)机制在写密集场景下可能增加内存与 CPU 开销。
❌ 可读性差二进制格式文件,无法直接查看内容,不利于调试与人工分析。
AOF✅ 数据安全性高记录每一个写命令,支持 appendfsync everysec 或 always数据丢失风险极低
✅ 可读性强纯文本记录 Redis 命令(如 SET key value),便于查看、审计和手动修复。
❌ 文件体积大持续记录所有写操作,日志文件远大于 RDB,占用更多磁盘空间。
⚠️ 写性能影响每次写操作需追加日志,I/O 压力增大,高并发下可能影响吞吐量(可通过配置优化)。
❌ 恢复速度慢重启时需重放所有命令,数据量大时恢复时间显著长于 RDB。

http://www.dtcms.com/a/428974.html

相关文章:

  • 做网站看深圳平湖网站开发
  • 海外网站速度慢网站留言功能
  • 山东省城乡与住房建设厅网站首页做网站资讯运营
  • 网站建设需要哪些岗位推广链接代点
  • 广安 网站建设c 网站开发实例
  • 搜索引擎网站排名优化方案wordpress主题设置
  • 使用Ray进行大规模并行智能体仿真
  • 棋牌游戏网站建设费用网络营销策划书范文
  • 传统workqueue
  • 对做网站公司的疑问防伪查询网站
  • 南联网站建设公司wordpress 教垜
  • 建设部网站 挂证企业网络营销策划案
  • 网站栏目结构哪些买域名的网站
  • 亚马逊网站建设进度计划深圳工程建设交易服务中心网站
  • 卖机器的网站怎么做创意网
  • 北京做网站建设的公司长沙科技公司排名
  • 20250931在RK3399的Buildroot【linux-6.1】下关闭camera_engine_rkisp
  • 网站建设这块是怎么挣钱的做网站学的是代码吗
  • “爬虫逆向——RPC技术”在反爬对抗中的破局实践:从Hook到链路级伪造
  • 那个旅游网站可以做行程专业的营销型网站制作
  • 怎么做百度提交入口网站找活做的网站
  • 企业网站托管代运营莆田有哪些网站建设公司
  • 购物网站技术实施方案佛山百度网站排名
  • 12306建网站多少钱wordpress找回管理员密码
  • 温州红酒网站建设互联网保险和线下保险的区别
  • 使用原生开发时 checkbox 单击事件会触发两次
  • 国外网站模板网站建设深圳互联网公司排行榜
  • 网站开发设计中的收获如何自己做视频网站
  • 集团网站开发多少钱企业展厅设计专业的公司
  • 上海建网站手机app南宁百姓网官网