Skip to content

Redis持久化

核心思想:为什么需要持久化?

Redis是一个基于内存的数据库,其高速性能源于此,但也带来了致命弱点:一旦服务器宕机,所有内存数据将全部丢失。为了解决这个问题,Redis提供了持久化机制,将内存中的数据保存到磁盘,以便在服务重启时能够恢复数据,避免了从后端慢速数据库恢复数据的巨大压力和性能瓶颈。

Redis主要支持两种持久化方式:RDB(快照)AOF(只追加文件)


一、 RDB (Redis DataBase) 持久化 - 快照模式

RDB的核心思想是在某一时间点,将Redis内存中的数据完整地生成一个快照文件(dump.rdb)

1. 触发方式

  • 手动触发
    • save: 阻塞主进程,直到快照完成。线上禁用
    • bgsave: 非阻塞。主进程fork一个子进程来执行快照,主进程继续处理客户端请求。这是推荐的方式。
  • 自动触发
    • redis.conf中配置save <seconds> <changes>规则,例如save 900 1表示900秒内有1次写入,则自动触发bgsave
    • 主从复制时,从节点请求全量同步,主节点会触发bgsave
    • 执行shutdown命令(且未开启AOF时)。
    • 执行debug reload命令。

2. bgsave 工作流程与原理

  1. 主进程fork一个子进程。fork过程是阻塞的,但通常很快。
  2. fork利用写时复制(Copy-on-Write, COW)机制。子进程共享父进程的内存页表,不立即复制物理内存。
  3. 子进程负责读取内存数据,并将其写入一个临时的RDB文件
  4. 在子进程写快照期间,如果主进程接收到写命令并需要修改某块数据,操作系统会复制这块数据的物理内存页,让主进程修改副本,而子进程继续读取原始数据,保证了快照的一致性。
  5. 子进程完成快照后,用原子操作将临时文件替换掉旧的dump.rdb文件。
  6. 子进程退出,通知主进程完成。

3. RDB 优缺点

  • 优点
    • 恢复速度快:RDB文件是紧凑的二进制格式,加载它来恢复数据远快于AOF。
    • 文件体积小:经过压缩(如LZF),文件体积远小于内存数据大小,适合备份和数据传输。
  • 缺点
    • 数据丢失风险高:RDB是定时快照,如果两次快照之间发生宕机,会丢失这段时间的所有数据,无法做到秒级持久化。
    • fork开销大fork子进程是重量级操作,会消耗CPU和内存资源,频繁执行成本高,可能导致主进程短暂阻塞。

二、 AOF (Append Only File) 持久化 - 日志模式

AOF的核心思想是将Redis执行的每一个写命令都以文本协议格式记录到一个日志文件中。

1. AOF 实现机制 - “写后日志”

Redis采用“写后日志”策略,即先执行命令修改内存数据,成功后再记录日志。 * 优点:避免了对命令的语法检查,且不会阻塞当前写操作。 * 潜在风险:如果在写完内存、但还未写入日志时宕机,会丢失该命令的数据。

AOF的完整过程分为三步:命令追加 (append) -> 文件写入 (write) -> 文件同步 (sync)

2. 写回策略 (appendfsync)

控制何时将日志真正写入磁盘,体现了性能与可靠性的权衡(trade-off)。

  • always: 同步写回。每个命令执行完后,立刻fsync到磁盘。最安全,但性能最差
  • everysec (默认): 每秒写回。命令先写入内核缓冲区,每秒钟由一个后台线程执行一次fsync性能和安全的最佳折中,最多丢失1秒数据
  • no: 操作系统控制。由操作系统决定何时将缓冲区数据刷到磁盘。性能最好,但最不安全

3. AOF 重写 (Rewrite) - 文件瘦身

为了解决AOF文件无限增大的问题,Redis提供了AOF重写机制。

  • 原理:不是读取旧的AOF文件进行优化,而是fork一个子进程,直接读取当前内存中的数据,并为每个键生成一条最优的写入命令,最终生成一个全新的、更小的AOF文件。例如,对一个计数器的100次INCR操作,在重写后会变成一条SET命令。
  • 触发时机:由auto-aof-rewrite-percentageauto-aof-rewrite-min-size两个配置项自动触发。
  • 重写过程中的数据一致性
    1. 主进程fork出重写子进程。
    2. 在子进程重写期间,主进程接收到的新写命令会同时写入旧的AOF缓冲区AOF重写缓冲区
    3. 子进程完成重写后,通知主进程。
    4. 主进程将AOF重写缓冲区中的增量命令追加到新AOF文件的末尾。
    5. 用原子操作将新文件替换旧文件。

4. AOF 优缺点

  • 优点
    • 数据可靠性高:根据写回策略,最多只丢失1秒的数据。
    • 可读性好:AOF文件是文本格式,易于理解和修复。
  • 缺点
    • 文件体积大:相比RDB,AOF文件通常更大。
    • 恢复速度慢:恢复时需要逐条执行命令,速度远慢于RDB。
    • 存在fork开销:AOF重写同样需要fork子进程。

三、 RDB 和 AOF 混合模式 (Redis 4.0+)

为了结合两者的优点,Redis 4.0引入了混合持久化。

  • 工作方式:当触发AOF重写时,fork的子进程不再是生成命令,而是将当前内存数据以RDB格式写入新AOF文件的开头,然后主进程将重写期间的增量写命令以AOF格式追加到文件末尾。
  • 优势
    • 快速恢复:加载时,先像RDB一样快速加载文件头部的快照部分。
    • 高可靠性:再加载文件末尾的AOF增量日志,保证了数据的完整性。
    • 这个方案是目前生产环境中的主流选择

四、 数据恢复与实践

恢复流程

  • Redis重启时,会优先加载AOF文件(如果开启了AOF),因为它通常包含更完整的数据。
  • 如果AOF加载失败或不存在,才会去加载RDB文件。

线上实践建议

  1. 性能优先,数据可重建:可以关闭持久化。
  2. 数据安全:开启混合持久化模式是最佳实践。
  3. 降低fork影响
    • 控制Redis实例的最大内存,避免fork耗时过长。
    • 避免多个实例在同一时间点进行持久化或重写操作。
    • 在主从架构中,可以利用从节点来执行RDB备份,不影响主节点的性能。
  4. 合理配置:根据业务场景调整save策略和AOF重写触发条件。

总结表

特性 RDB (快照) AOF (日志) 混合模式 (推荐)
数据可靠性 较低,丢失上次快照至今的数据 高,最多丢失1秒数据 (everysec策略) 高,同AOF
文件大小 小,二进制压缩 大,文本日志,需重写瘦身 较小,RDB头部+AOF尾部
恢复速度 快,直接加载内存镜像 慢,需重放所有命令 快,先加载RDB部分,再重放少量AOF增量
核心机制 fork + 写时复制 (COW) 命令追加 + 写回策略 + fork重写 AOF重写时,生成RDB格式文件头+AOF格式增量
适用场景 数据备份、灾难恢复、主从复制全量同步 对数据完整性要求高的场景 绝大多数生产环境