Redis 的持久化机制是其高可用性的基石,主要包含 RDB (Redis Database)AOF (Append Only File) 两种方式,它们的设计目标、实现原理和适用场景各有不同。

一、RDB (Redis Database) - 快照

  1. 原理:

    • RDB 在指定的时间间隔内,将内存中整个 Redis 数据集生成一个时间点快照 (Point-in-Time Snapshot)。
    • 生成快照的过程:
      • Redis 主进程 fork 出一个子进程
      • 子进程将内存中的数据序列化写入一个临时的 RDB 文件。
      • 在子进程完成写入后,用这个新的 RDB 文件替换旧的 RDB 文件(rename 操作是原子的)。
    • RDB 文件是一个二进制压缩文件,结构紧凑。
  2. 触发方式:

    • 手动触发:

      • SAVE: 阻塞 Redis 主进程,直到 RDB 文件创建完毕。生产环境几乎不用,会导致服务长时间不可用。
      • BGSAVE: 后台异步进行快照生成。Redis 会 fork 子进程来完成工作,主进程继续提供服务。推荐使用
    • 自动触发:
      • 根据配置文件 redis.conf 中的 save <seconds> <changes> 规则触发 BGSAVE。例如:

        • save 900 1: 900秒(15分钟)内有至少1个key发生变化。
        • save 300 10: 300秒(5分钟)内有至少10个key发生变化。
        • save 60 10000: 60秒内有至少10000个key发生变化。
      • 执行 SHUTDOWN 命令关闭服务器时(如果未配置 AOF 或 AOF 未开启)。
      • 主从复制时,主节点收到 SYNC 命令开始全量复制时会自动触发 BGSAVE 生成 RDB 发送给从节点。
  3. 优点:

    • 性能高,恢复速度快: RDB 文件是紧凑的二进制文件,生成和加载(启动恢复)都非常快,非常适合大规模数据恢复和灾难恢复。
    • 磁盘空间占用小: 二进制压缩格式显著减小了磁盘占用。
    • 最大化 Redis 性能: BGSAVE 由子进程完成,主进程只承担 fork 的短暂开销,对读写服务影响较小。
    • 适合备份: 单个文件方便备份和传输到远程数据中心或云存储。
  4. 缺点:

    • 数据丢失风险高: 两次快照之间的数据修改会丢失。如果配置为每5分钟保存一次,服务器故障可能丢失最多5分钟的数据。对数据安全性要求高的场景不合适。
    • fork 可能阻塞服务: 如果数据集非常大(例如几十GB),fork 操作本身可能比较耗时(尤其是在虚拟机上),导致主进程短暂停顿(毫秒到秒级),影响服务响应时间。
    • 版本兼容性: 老版本 Redis 生成的 RDB 文件可能无法在新版本 Redis 上恢复。

二、AOF (Append Only File) - 日志追加

  1. 原理:

    • AOF 记录 Redis 服务器收到的每一条写命令(及其参数)。
    • 这些命令以 Redis 协议格式追加写入到 AOF 文件的末尾。
    • Redis 重启时,通过重新执行 AOF 文件中的所有写命令来重建内存数据集状态。
    • AOF 重写: 为了解决 AOF 文件不断膨胀的问题,Redis 会定期根据内存中的当前数据状态,创建一个新的、更小的 AOF 文件来替换旧的。重写过程由子进程完成(类似 BGSAVE),期间新的写命令会同时记录到内存缓冲区旧的 AOF 文件中。重写完成后,缓冲区内容追加到新 AOF 文件,然后原子替换旧文件。
  2. 触发方式与配置:

    • 开启 AOF:redis.conf 中设置 appendonly yes
    • 写入策略 (appendfsync): 控制何时将 AOF 缓冲区的内容同步到磁盘,这是影响性能和数据安全性的关键配置。
      • no: 由操作系统决定何时同步。性能最好,但数据丢失风险最高(操作系统缓存未写入磁盘的数据在宕机时会丢失)。
      • always: 每个写命令都同步到磁盘。数据最安全(最多丢失一个命令),但性能最差(磁盘 I/O 成为瓶颈)。
      • everysec (默认): 每秒同步一次。在性能和数据安全性之间取得良好平衡。理论上最多丢失1秒的数据。这是最常用的配置。
    • AOF 重写触发:
      • 手动触发:执行 BGREWRITEAOF 命令。
      • 自动触发:根据 redis.conf 中的 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 配置。例如:
        • auto-aof-rewrite-percentage 100 (当前 AOF 文件大小比上次重写后的大小增长了100%)
        • auto-aof-rewrite-min-size 64mb (且当前 AOF 文件大小至少达到 64MB)
  3. 优点:

    • 数据安全性高: 默认的 everysec 策略最多丢失1秒数据,always 策略理论上不丢失数据(但性能极低)。非常适合对数据完整性要求高的场景。
    • 可读性(一定程度上): AOF 文件是文本格式(Redis 协议),便于人工理解和修复(虽然通常不直接编辑)。
    • 容灾性强: 即使文件末尾因故障写入不完整,Redis 自带工具 redis-check-aof 可以轻松修复(删除不完整的命令)。
    • 后台重写: BGREWRITEAOF 由子进程执行,不影响主进程服务。
  4. 缺点:

    • 文件体积大: 相比同数据集的 RDB 文件,AOF 文件通常更大(即使经过重写)。
    • 恢复速度慢: 重新执行所有命令来恢复数据,比加载 RDB 文件慢得多,尤其当 AOF 文件很大时。
    • 性能略低于 RDB: 即使使用 everysec,AOF 的写入吞吐量通常也低于 RDB(尤其是在大量写入场景下)。always 策略性能影响显著。
    • 历史 Bug: AOF 重写逻辑在极端情况下(如断电)曾出现过一些边界 Bug(虽然现在已比较成熟)。

三、如何选择 RDB 和 AOF?

没有绝对的最佳答案,选择取决于你的应用对数据安全性性能的要求:

  1. 追求最高性能,能容忍分钟级数据丢失:

    • 仅使用 RDB。 这是最简单的配置,适合缓存、会话存储等对丢失少量数据不敏感的场景。配置好 save 规则即可。
  2. 追求高数据安全性,能接受一定的性能损失和较慢的恢复速度:

    • 仅使用 AOF (appendfsync everysec)。 这是最常见的生产环境配置,在性能和安全性之间取得了很好的平衡。适用于需要持久化订单、交易、用户状态等关键数据的场景。强烈建议启用 AOF。
  3. 需要非常高的数据安全性,能容忍显著性能下降:

    • 仅使用 AOF (appendfsync always)。 牺牲性能换取最高的数据安全性(理论上零丢失)。仅在极端要求数据一致性的场景使用(如金融核心交易),通常需要配合高性能 SSD 磁盘。
  4. 希望平衡性能和数据安全性,并需要快速恢复能力:

    • 同时启用 RDB 和 AOF (推荐方式)。

      • 数据安全: 依赖 AOF (appendfsync everysec)。
      • 快速恢复: 依赖 RDB。可以定期(如每天)手动执行 BGSAVE 备份 RDB,或者在配置中保留合理的 save 规则(但频率可以设低一些,如 save 3600 1 每小时保存一次)。
      • 重启恢复流程: Redis 重启时优先使用 AOF 文件来恢复数据(因为它通常包含更完整的数据集状态)。只有当 AOF 功能关闭时,才会使用 RDB 文件恢复。
    • Redis 4.0+ 的混合持久化:
      • redis.conf 中设置 aof-use-rdb-preamble yes
      • AOF 重写时,子进程将内存数据以 RDB 格式写入新的 AOF 文件的开头部分(preamble),然后将重写期间缓冲的增量写命令以 AOF 格式追加到文件后面。
      • 优点: 结合了 RDB 的快速加载(加载开头 RDB 部分)和 AOF 的数据完整性(加载后续增量命令)。生成的混合文件通常比纯 AOF 文件小,加载速度比纯 AOF 快很多。这是目前非常推荐的生产环境配置方式。

总结与建议

  • 理解风险: 评估应用能容忍多少数据丢失(RPO - Recovery Point Objective)。
  • 基准测试: 在你的硬件和工作负载下测试不同配置的性能(吞吐量、延迟)。
  • 生产推荐:
    • 首选方案: 同时启用 RDB 和 AOF (appendfsync everysec),并开启混合持久化 (aof-use-rdb-preamble yes)。这提供了最佳的数据安全性和较好的恢复速度。
    • 纯 AOF (appendfsync everysec) 也是一个非常稳健的选择。
    • 尽量避免仅使用 RDB,除非数据完全不重要。
  • 监控与运维:
    • 监控磁盘空间(AOF 文件可能很大)。
    • 监控 fork 耗时(info stats 中的 latest_fork_usec)。
    • 定期备份 RDB/AOF 文件到异地。
    • 根据数据增长情况调整 AOF 重写触发条件 (auto-aof-rewrite-*)。
    • 预留足够的磁盘 I/O 能力给 AOF。

最终选择应基于你的具体业务需求、数据重要性、性能预算和运维能力进行权衡。在 Redis 4.0+ 环境下,开启混合持久化通常是满足大多数生产环境需求的最佳实践。

【🔥🔥🔥RDB还是AOF ?】Redis持久化原理全景解读与生产级决策手册的更多相关文章

  1. 【Java面试】RDB 和 AOF 的实现原理、优缺点

    Hi,大家好,我是Mic. 一个工作了5年的粉丝私信我,最近面试碰到很多Redis相关的问题. 其中一个面试官问他Redis里面的持久化机制,没有回答得很好. 希望我帮他系统回答一下. 关于Redis ...

  2. redis 实战操作RDB和AOF快照持久化

    前言:redis是我们常用的缓存方式,今天就来介绍下两种持久化的方式吧,先科普概念,再实战操作 一.RDB Redis将某一时刻的快照(备份的数据库数据)保存成一种称为RDB格式的文件中,这种格式是经 ...

  3. 两种Redis持久化原理的详解

    Redis为持久化提供了两种方式: RDB:在指定的时间间隔能对你的数据进行快照存储. AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据. 本文将通过下面内容的介 ...

  4. redis的 rdb 和 aof 持久化的区别

    aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...

  5. Redis 持久化之RDB和AOF

    Redis 持久化之RDB和AOF Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File).如果你想快速了解和使用RDB和AOF,可以直 ...

  6. redis两种持久化方式RDB和AOF

    目录 前言 1. Redis 数据库结构 2. RDB 持久化 2.1. RDB 的创建和载入 2.1.1. 手动触发保存 SAVE 命令 BGSAVE 命令 SAVE 和 BGSAVE 的比较 2. ...

  7. Redis持久化存储——>RDB & AOF

    Redis中两种持久化存储机制RDB和AOF redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB ...

  8. redis 持久化 AOF和 RDB 引起的生产故障

    概要       最近听开发的同事说,应用程序连接 redis 时总是抛出连接失败或超时之类的错误.通过观察在 redis 日志,发现日志中出现 "Asynchronous AOF fsyn ...

  9. 配置方案:Redis持久化RDB和AOF

    Redis持久化方案 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘.当下次Redis重启时,利 ...

  10. Linux - redis持久化RDB与AOF

    目录 Linux - redis持久化RDB与AOF RDB持久化 redis持久化之AOF redis不重启,切换RDB备份到AOF备份 确保redis版本在2.2以上 实验环境准备 备份这个rdb ...

随机推荐

  1. 【工具】FreePic2PDF+PdgCntEditor|PDF批量添加书签(Windows)

    这俩软件都不大,比较便携. FreePic2PDF: 我下载的来源:https://www.52pojie.cn/thread-1317140-1-1.html(包含下载链接https://www.l ...

  2. 【BUG】Message = “无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。“, StackTrace = “ 在 System.Reflection.

    环境: Visual Studio 2019 C#项目遇到这种情况时,是因为有多个依赖出了问题(也可能是只有一个但被误报成多个),此时点开"查看详细信息",可以快速监视Except ...

  3. CLion打开VS创建的GBK编码格式的项目中文乱码问题的解决方法

    在 CLion 中设置 GBK 编码用于编译代码时,如果输出的 message 乱码,通常是由于控制台编码与代码文件的编码不匹配导致的.以下是解决问题的步骤: 1. 设置文件编码为 GBK 确保你的源 ...

  4. 人工神经网络(ANN)模型

    一.概述   人工神经网络(Artificial Neural Network,ANN),是一种模拟生物神经网络结构和功能的计算模型,它通过大量的神经元相互连接,实现对复杂数据的处理和模式识别.从本质 ...

  5. MACD、RSI、Boll以及分型指标的实现与回测

    对指标的实现 分为两部分: 信号的计算 实现信号算法 检测历史信号 保存到数据库 信号使用 提供查询接口 我们将信号的计算与回测分离开,将计算后的信号结果保存到数据库中,供回测时调用,模式图如下: 指 ...

  6. C#之方法

    在C#中,方法是类的函数成员,方法由两个主要部分: (1)方法头:指定了方法的特征,包括是否返回数据,如果返回,返回什么类型;方法的名称;哪种类型的数据可以传递给方法或从方法返回,以及如何处理这些数据 ...

  7. python3里面实现将日志文件写入当前脚本运行的文本中

    在 Python3 中,可以使用 logging 模块来实现将日志写入本地文本文件中.下面是一个简单的示例代码: import logging # 配置 logging 模块 logging.basi ...

  8. Spring Boot 使用Apollo动态调整日志级别

    摘要:在Spring Boot 项目中,借助Apollo动态修改配置的能力,结合Logback修改日志级别打印执行的SQL脚本. 综述   在生产环境偶现测试环境未发现的SQL查询BUG,但由于线上关 ...

  9. Android studio虚拟机黑屏

    1.冷启动 cold boot now 2.新建一个 另外今天下午起来的比较晚,就在宿舍上的机,然后效果就比较差,我有罪,我下次要学习一定不在宿舍,今晚也是早早的吃了饭就来自习了,这就是成果.卡了我一 ...

  10. 提升PHP并行处理效率:深入解析数组排序算法及优化策略

    本文由 ChatMoney团队出品 在 PHP 开发中,数组排序是一个常见的操作.随着互联网技术的不断发展,对数据处理速度和效率的要求越来越高,如何在保证排序质量的同时提高处理速度成为了一个值得探讨的 ...