【redis】持久化之RDB与AOF

news2025/3/31 12:22:04

在数字世界的脉搏中,数据是流淌的血液,而持久化则是保障系统生命力的核心机制。作为内存数据库的标杆,Redis凭借其高性能特性成为互联网架构的基石,但其「易失性」的天然属性也催生了关键命题:如何在服务重启或故障时保障数据安全?

从RDB快照的瞬时记忆到AOF日志的精准回放,再到混合持久化的智慧融合,Redis用三种递进式的方案回答了这一问题。RDB以二进制快照实现高效备份,AOF以日志追加构筑数据保险,而混合模式则通过「全量快照+增量日志」的架构,在恢复效率与数据安全之间找到黄金平衡点。

RDB持久化

RDB(Redis Database)是Redis默认的持久化方式,通过在指定的时间间隔内对内存中的全量二进制数据进行快照存储实现数据持久化。

RDB是一个非常紧凑的单一文件,它保存了某个时间点的全量数据集,非常适用于数据集的备份。保存RDB文件时父进程唯一需要做的就是调用系统函数fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。

由于RDB的文件内容紧凑,对数据进行了压缩,不像AOF一样数据中存在过期的key和重复的指令,所以在恢复大的数据集的时候,RDB方式会更快一些。

核心原理

其工作原理可概括为:

  • 定时快照:根据配置文件save 900 1等规则(900秒内有1次修改即触发),通过fork子进程异步生成dump.rdb文件

  • 手动触发:支持SAVE(同步阻塞)和BGSAVE(后台异步)两种指令

  • 写时复制:主进程持续处理请求,子进程通过Copy-On-Write技术生成内存镜像

redis.conf中跟rdb相关的核心配置:

# 60秒内有至少有1000个键被改动时,自动触发RDB
# 300秒内有至少有10个键被改动时,自动触发RDB
# 900秒内有至少有1个键被改动时,自动触发RDB
save 900 1
save 300 10
save 60 10000

# 异步重写失败了,会停止写入
stop-writes-on-bgsave-error yes

# 开启rdb文件压缩
rdbcompression yes

# 加载rdb和保存rdb时文件进行校验
rdbchecksum yes

# rdb存储的文件名,保存路径在下面
dbfilename dump.rdb

# 在没有持久化的情况下删除复制中使用的RDB文件,通常情况下保持默认即可。
rdb-del-sync-files no

# RBD文件保存的目录
dir /usr/local/redis/data/6379

跟rdb相关的命令:

  • save:同步阻塞生成快照。

  • bgsave:后台异步生成快照。

fork的原理

RDB时需要考虑的两个问题:

  1. 假如8点开始RDB,整个过程需要持续5分钟,那么在这5分钟有些key被修改了,有些key被删除了,那么这些key会不会被存储到RDB文件中去呢?

  2. 如果有用另外一个进程来负责持久化,那么是不是需要将整个redis进程的内存拷贝一份,时间成本会不会很大,内存空间是不是够用?

上面的这两个问题都能从fork的原理中找到答案。

fork是linux提供的一个系统调用,其声明如下:

#include <unistd.h>
pid_t fork(void);

返回值pid_t是进程描述符,实质就是一个int,如果fork函数调用失败,返回一个负数-1,调用成功则返回两个值:0和子进程ID,对于子进程来说返回值为0,对于父进程来说返回的是子进程的ID。

下面通过一个c语言代码来演示fork的原理:

#include<stdio.h>
#include<unistd.h>

int main() {
    int i = 10;
    pid_t pid = fork();

    if(pid > 0) {
    i--;
    printf("i am parent process, id:%d\n", getpid());    
        printf("i am parent process, i=%d\n", i);
        sleep(20);
    } else if(pid == 0) {
        printf("i am child process, pid:%d, ppid:%d\n", getpid(), getppid());
        i++;
        printf("i am child process, i=%d\n", i);
        sleep(20);
    }    

}

运行结果如下:

i am parent process, id:14848
i am parent process, i=9
i am child process, pid:14849, ppid:14848
i am child process, i=11

说明:

  1. fork系统调用之后,父进程和子进程一般会交替执行,并且它们处于不同空间中。

  2. fork()的子进程并不是从头开始,因为在fork()之前,父进程已经为子进程搭建好了运行环境了,所以直接从有效代码处开始。

  3. fork底层实现采用了写时拷贝(COW,copy_on_write)技术,父进程和子进程共享页帧而不是复制页帧。然而,只要页帧被共享,它们就不能被修改,即页帧被保护。无论父进程还是子进程何时试图写一个共享的页帧,就产生一个异常,这时内核就把这个页复制到一个新的页帧中并标记为可写。原来的页帧仍然是写保护的:当其他进程试图写入时,内核检查写进程是否是这个页帧的唯一属主,如果是,就把这个页帧标记为对这个进程是可写的。

RDB导致数据丢失问题

由于RDB每次都是进行全量数据的备份,所有这种操作不可能很频繁,不然会影响IO性能,所以RDB会有一个时间间隔,假如这个时间间隔为5分钟,8点整进行了一次RDB,在8点05分点刚要进行RDB的时候,redis意外停止工作(例如停电),这样就会导致8点到8点05分点这个时间段的数据的丢失,如果你能容忍这种数据的丢失的情况,那么就可以使用RDB,一般来说,redis用来做缓存,数据丢失了没关系,可以从数据库中再次加载到redis中。但是如果把redis当成数据库使用的话,那么就不适合使用RDB这种持久化方式了。

RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来调节。

子进程将数据集写入到一个临时RDB文件中,当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的RDB文件,并删除旧的RDB文件。

核心优势

  1. 高性能:二进制压缩存储,数据恢复速度比AOF快3-5倍

  2. 紧凑存储:适合灾难恢复,单文件便于传输与备份

  3. 低资源消耗:后台生成快照时主进程仅短暂阻塞

使用限制

  1. 数据丢失风险:最后一次快照后的修改可能丢失(典型场景丢失5-15分钟数据)

  2. 大内存压力:fork子进程时可能产生内存翻倍现象

  3. 版本兼容性:旧版RDB文件无法直接用于新版Redis

AOF持久化

AOF(Append Of File):记录每次对服务器写的操作,以RESP(REdis Serialization Protocol)协议追加保存每次写的操作到文件末尾。

由于AOF中会存在一些过期的key,以及对一个key的多次写操作都会以redis协议格式追加在文件中尾部,并没有进行压缩,所以会导致AOF文件的体积不断变大,为了解决文件过大的问题,AOF会自动地在后台对文件进行重写。

工作机制

AOF(Append Only File)通过记录写操作命令实现持久化:

  • 命令追加:每个写命令以Redis协议格式追加到缓冲区

  • 同步策略:根据配置文件中的策略将缓存区中的命令写入磁盘中

  • 重写机制:通过BGREWRITEAOF消除冗余命令,生成紧凑的新AOF文件

redis.conf中跟aof相关的核心配置:

# AOF默认关闭
appendonly no

# The name of the append only file (default: "appendonly.aof")
# AOF保存的文件名
appendfilename "appendonly.aof"

# 同步的模式
# always:每收到一个写请求就同步到文件中,这样就不会丢失数据,但是性能低(每次都有磁盘IO)。
# everysec:每秒同步一次,最多丢失一秒的数据,性能介于always和no之间。
# no:no并不是不同步,而是redis只把数据写到操作系统的缓冲区中,具体什么时候写到磁盘依赖操作系统,linux下缓存区大小为512k,缓冲区买了才会刷新到磁盘,性能最好。

# appendfsync always
appendfsync everysec
# appendfsync no

# AOF重写期间不进行同步,避免大量的磁盘IO,影响性能
no-appendfsync-on-rewrite no


# 配置重写触发机制,当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 如果该配置启用,在加载时发现aof尾部不正确时会向客户端写入一个log,但是会继续执行,如果设置为no,发现错误就会停止,必须修复后才能重新加载。
aof-load-truncated yes

跟aof相关的命令:

  • bgrewriteaof:手动触发aof的重写操作。

可以通过下面的命令开启aof:

127.0.0.1:6379> config set appendonly yes
OK

127.0.0.1:6379> config set appendfsync everysec
OK

Redis默认在首次开启AOF时可能不会立即生成文件(即使设置了每秒同步写磁盘),需手动执行BGREWRITEAOF命令才会触发aof文件生成。

Redis可以在AOF文件体积变得过大时,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。

AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析也很轻松,导出AOF文件也非常简单。如果你不小心执行了FLUSHALL命令,但只要AOF文件未被重写,那么只要停止服务器,移除AOF文件末尾的FLUSHALL命令,并重启Redis,就可以将数据集恢复到FLUSHALL执行之前的状态。

对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积,根据所使用的fsync策略,AOF的速度可能会慢于RDB。

核心优势

  1. 数据完整性:最大程度避免数据丢失(everysec模式最多丢失1秒数据)

  2. 可读性强:文本格式便于人工审计与修复

  3. 容灾灵活:支持断点续传式数据恢复

使用限制

  1. 文件体积大:相同数据集AOF文件通常比RDB大2-5倍

  2. 恢复速度慢:重放命令方式导致恢复耗时较长

  3. 写入压力大:高并发场景可能触发磁盘I/O瓶颈

混合持久化模式

Redis 4.0+引入的混合模式结合RDB与AOF的优势。

实现原理

混合模式的前面流程与AOF的流程类似,在重写时是生成RDB快照:

  1. 存储结构:AOF文件包含RDB头部(全量数据)和增量AOF日志

  2. 触发条件:AOF重写时自动生成RDB格式的全量数据快照

  3. 恢复流程:优先加载RDB部分恢复基础数据集,重放后续AOF命令补充增量修改

redis.conf中跟aof相关的核心配置:

# 启用混合模式,AOF文件的内容前面是否使用RDB
aof-use-rdb-preamble yes  

核心优势

  1. 恢复效率提升:比纯AOF恢复速度提升80%以上

  2. 数据安全性保留:仍保持AOF的秒级数据持久化能力

  3. 存储空间优化:RDB压缩减少磁盘占用,AOF增量保持精简

适用场景

  1. 需要兼顾数据安全与恢复速度的生产环境

  2. 存在明显冷热数据分层的业务场景

  3. 需要跨版本迁移数据的特殊场景

方案对比

维度RDBAOF混合模式
数据安全性分钟级丢失秒级丢失秒级丢失
恢复速度最快(GB/秒)较慢(命令重放)较快(RDB+AOF)
磁盘占用最小最大中等
写入性能影响瞬时压力持续压力均衡压力

注:实际部署建议同时开启RDB和AOF,通过aof-use-rdb-preamble参数启用混合模式,并定期进行备份验证

启动过程中数据加载流程


Redis在启动时优先加载AOF文件(appendonly.aof)恢复数据,仅当AOF未启用(appendonly no)或AOF文件不存在时,才会加载RDB文件(dump.rdb)。

原因:

  • AOF记录所有写操作命令,通常比RDB快照包含更完整的数据(如两次RDB快照之间的操作)。

  • Redis默认将AOF视为更可靠的持久化方式(除非明确禁用)。

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

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

相关文章

Brainstorm绘制功能连接图(matlab)

上篇笔记简单介绍了Brainstorm&#xff0c;本次使用Brainstorm绘制功能连接图。而对于连接矩阵&#xff0c;软件中有几种方法&#xff1a;相关、相干、双变量格兰杰因果关系、相位锁相值、包络相关、相位转移熵。 首先&#xff0c;对数据进行预处理&#xff0c;保存为.set&…

华为HG532路由器RCE漏洞 CVE-2017-17215 复现

华为HG532路由器RCE漏洞 CVE-2017-17215 CVE-Description Huawei HG532 with some customized versions has a remote code execution vulnerability. An authenticated attacker could send malicious packets to port 37215 to launch attacks. Successful exploit could l…

LVS的三种工作模式简述

一、引言 在过去的十几年中&#xff0c;Internet从几个研究机构相连为信息共享的网络发展成为拥有大量应用和服务的全球性网络&#xff0c;它正成为人们生活中不可缺少的 一部分。虽然Internet发展速度很快&#xff0c;但建设和维护大型网络服务依然是一项挑战性的任务&#xf…

使用 Layers 扩展你的 Nuxt4 应用

面对一个臃肿的页面或项目&#xff0c;你会如何简化重构、扩展它&#xff1f; 当单个 Vue 文件中界面/业务足够多时&#xff0c;通常我们会把它拆分成多个 components 或 composables 来引入&#xff0c;以此来减少此文件复杂度和增加可维护性。 当一个项目的界面/业务逻辑足…

Excel处理控件Aspose.Cells指南:如何在不使用 Microsoft Excel 的情况下解锁 Excel 工作表

Microsoft Excel 允许用户使用密码保护工作表&#xff0c;以防止未经授权的更改。但是&#xff0c;在某些情况下&#xff0c;您可能需要在不使用 Microsoft Excel 的情况下解锁 Excel 工作表。在本指南中&#xff0c;我们将探讨解锁 Excel 工作表的不同方法&#xff0c;例如使用…

进军场景智能体,云迹机器人又快了一步

&#xff08;图片来源&#xff1a;Pixels&#xff09; 2025年&#xff0c;AI和机器人行业都发生了巨大改变。 数科星球原创 作者丨苑晶 编辑丨大兔 2025年&#xff0c;酒店行业正掀起一股批量采购具备AI功能的软硬一体解决方案的热潮。 在DeepSeek、Manus等国产AI软件的推动…

PHP 应用SQL 注入符号拼接请求方法HTTP 头JSON编码类

#PHP-MYSQL- 数据请求类型 SQL 语句由于在黑盒中是无法预知写法的&#xff0c; SQL 注入能发成功是需要拼接原 SQL 语句&#xff0c; 大部分黑盒能做的就是分析后各种尝试去判断&#xff0c;所以有可能有注入但可能出现无法注入成 功的情况。究其原因大部分都是原 SQL …

【React】基础版React + Redux实现教程,自定义redux库,Redux Toolkit教程

本项目是一个在react中&#xff0c;使用 redux 管理状态的基础版实现教程&#xff0c;用简单的案例练习redux的使用&#xff0c;旨在帮助学习 redux 的状态管理机制&#xff0c;包括 store、action、reducer、dispatch 等核心概念。 项目地址&#xff1a;https://github.com/Yv…

23种设计模式-适配器(Adapter)设计模式

适配器设计模式 &#x1f6a9;什么是适配器设计模式&#xff1f;&#x1f6a9;适配器设计模式的特点&#x1f6a9;适配器设计模式的结构&#x1f6a9;适配器设计模式的优缺点&#x1f6a9;适配器设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是…

debug 笔记:llama 3.2 部署bug 之cutlassF: no kernel found to launch!

1 问题描述 按照官方的写法 import torch from transformers import pipeline import os os.environ["HF_TOKEN"] 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 model_id "meta-llama/Llama-3.2-3B"pipe pipeline("text-generation", modelmode…

TCP的长连接和短连接,以及它们分别适用于什么场合

TCP长连接与短连接详解 一、核心概念对比 特性长连接&#xff08;Persistent Connection&#xff09;短连接&#xff08;Short-lived Connection&#xff09;连接生命周期一次建立后长期保持&#xff0c;多次数据交互复用同一连接每次数据交互均需新建连接&#xff0c;完成后…

【操作系统】(五)操作系统引导(Boot)

视频参考&#xff1a;王道计算机2.了解计算机的启动过程和主引导扇区&#xff0c;让你的计算机从这里起飞吧_哔哩哔哩_bilibili 操作系统引导(Boot)就是在开机的时候&#xff0c;如何让操作系统运行起来&#xff1f; 主存分成RAM小部分ROM,其中ROM里面存放的是BIOS&#xff08…

蓝桥与力扣刷题(蓝桥 山)

题目&#xff1a;这天小明正在学数数。 他突然发现有些止整数的形状像一挫 “山”, 比㓚 123565321、145541123565321、145541, 它 们左右对称 (回文) 且数位上的数字先单调不减, 后单调不增。 小朋数了衣久也没有数完, 他惒让你告诉他在区间 [2022,2022222022] 中有 多少个数…

场馆预约小程序的设计与实现

摘 要 时代在进步&#xff0c;人们对日常生活质量的要求不再受限于衣食住行。现代人不仅想要一个健康的身体&#xff0c;还想拥有一身宛如黄金比例的身材。但是人们平常除了上下班和上下学的时间&#xff0c;其余空余时间寥寥无几&#xff0c;所以我们需要用体育场馆预约来节省…

Pytorch学习笔记(十二)Learning PyTorch - NLP from Scratch

这篇博客瞄准的是 pytorch 官方教程中 Learning PyTorch 章节的 NLP from Scratch 部分。 官网链接&#xff1a;https://pytorch.org/tutorials/intermediate/nlp_from_scratch_index.html 完整网盘链接: https://pan.baidu.com/s/1L9PVZ-KRDGVER-AJnXOvlQ?pwdaa2m 提取码: …

Axure项目实战:智慧运输平台后台管理端-母版、登录(文本框高级交互)

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;智慧运输平台后台管理端 主要内容&#xff1a;母版、登录页制作 应用场景&#xff1a;母版、登录、注册、密码找回 案例展示&#xff1a; 案例视频…

时序数据库 InfluxDB(一)

时序数据库 InfluxDB&#xff08;一&#xff09; 数据库种类有很多&#xff0c;比如传统的关系型数据库 RDBMS&#xff08; 如 MySQL &#xff09;&#xff0c;NoSQL 数据库&#xff08; 如 MongoDB &#xff09;&#xff0c;Key-Value 类型&#xff08; 如 redis &#xff09…

java开发环境本地全套

文章目录 1、jdk下载安装1.1、下载地址&#xff1a;1.2、安装1.3、验证 2、maven下载安装2.1、下载地址2.2、安装2.3、验证 3、git下载。3.1、下载地址 4、ideal下载5、dbeaver下载 1、jdk下载安装 1.1、下载地址&#xff1a; https://www.oracle.com/java/technologies/down…

华为配置篇-ISIS基础实验

ISIS 一、简述二、常用命令总结三、实验 一、简述 一、基本定义与历史背景 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种链路状态路由协议&#xff0c;最初由ISO设计用于OSI&#xff08;开放系统互联&#…

【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV3模型部署

【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署前言Windows平台搭建依赖环境模型转换--pytorch转onnxONNXRuntime推…