Skip to content

持久化与数据可靠性

RDB(快照)

简介

Redis 的 RDB(Redis Database Backup) 是一种基于快照的持久化机制,用于将内存中的数据集在某个时间点的状态保存到磁盘文件中(默认文件名为 dump.rdb)。

RDB 通过生成二进制压缩文件的方式持久化数据,其优势在于高效、紧凑和快速恢复,适合对数据一致性要求不苛刻的场景(允许少量数据丢失)。在实际应用中,通常结合业务需求调整快照触发频率,或与 AOF 持久化配合使用,以平衡性能和数据安全性

工作原理

  • 快照生成
    RDB 通过创建数据快照来实现持久化。
    快照生成时,Redis 会将内存中的所有数据以二进制格式写入磁盘文件。
  • 触发方式
    • 手动触发
      • save命令:阻塞主进程,客户端请求(包括读和写)都会被阻塞,直到快照生成完成。
      • bgsave命令(推荐):后台异步生成快照,Redis 会 fork 一个子进程执行持久化操作,主进程继续处理其它请求。
    • 自动触发 根据 redis.conf 中的配置规则自动触发 bgsave,满足任一条件时,自动触发快照。
      redis.conf RDB快照触发条件
      shell
      save 900 1       # 900秒(15分钟)内至少1个键被修改
      save 300 10      # 300秒(5分钟)内至少10个键被修改
      save 60 10000    # 60秒内至少10000个键被修改

配置

redis.conf RDB配置
shell
# RDB 文件名
dbfilename dump.rdb

# 保存路径
dir /opt/software/redis

# 自动触发规则
# 关闭RDB只需要将所有的save保存策略注释掉即可
save 900 1
save 300 10
save 60 10000

# 如果BGSAVE失败,是否停止写入(防止数据不一致)
stop-writes-on-bgsave-error yes

# 是否压缩RDB文件(节省空间,但略微增加CPU消耗)
rdbcompression yes

# 是否校验RDB文件(防止损坏)
rdbchecksum yes

RDB 优点

  • 紧凑高效 RDB 文件是压缩的二进制文件,体积小,适合备份和传输。
  • 快速恢复 加载 RDB 文件恢复数据的速度远快于 AOF(Append-Only File).
  • 适合灾难恢复 可将 RDB 文件备份到远程存储(如云存储)。
  • 低性能影响 BGSAVE 通过子进程处理,主进程无阻塞(除 fork 时的短暂延迟)。

RDB 缺点

  • 数据丢失风险 两次快照之间的数据可能丢失(取决于触发频率)。
  • Fork 的性能开销 数据集较大时,fork 子进程可能消耗较多内存和 CPU。
  • 不实时 无法实现秒级持久化(相比 AOF 的秒级同步)。

RDB 适用场景

  • 定期备份 例如每日备份 RDB 文件用于历史数据归档。
  • 快速重启恢复 在需要快速重启 Redis 时,直接加载 RDB 文件。
  • 大规模数据恢复 相比 AOF,RDB 恢复大数据集更快。
  • 与 AOF 结合使用 Redis 允许同时开启 RDB 和 AOF,结合两者的优点(RDB 用于定期备份,AOF 用于实时持久化)。

写时复制机制

简介

写时复制(Copy-on-Write,COW) 是一种资源管理技术,其核心思想是:在需要修改共享资源时,才真正复制并创建新副本,否则始终共享同一份原始数据。这种机制通过延迟复制操作,显著提升了资源利用率并减少了不必要的开销。

  • 初始共享
    当多个用户(如进程、线程或变量)需要访问同一份数据时,系统不会立即复制完整数据,而是让它们共享同一份原始资源
  • 按需复制
    当某一用户尝试修改共享数据时,系统才会触发复制操作,生成该数据的独立副本,且修改仅作用于新副本,原始数据保持不变
  • 透明性
    整个过程对用户透明,无需主动干预,操作系统自动处理复制和隔离

BGSAVE写时复制流程

  • fork 子进程
    • 调用fork()创建子进程,子进程与主进程共享同一份内存空间,父子进程的页表项标记为只读,进行页级保护
    • Linux在fork()后,父子进程的页表项标记为只读。
  • 生成 RDB 快照
    • 子进程遍历内存数据,将快照写入临时RDB文件
    • 写时复制(COW)
      当子进程正在将内存数据写入磁盘期间,若客户端发送更新内存的命令(如SET、DEL等),整个过程通过操作系统的页级保护和内存页复制实现同步
      • 页级保护:当主进程尝试在源内存页写数据时,触发页错误(Page Fault)
      • 内存页复制:尝试被修改的内存页会由操作系统复制一份,主进程在副本上修改,子进程仍读取原页
      • 隔离性:子进程看到的始终是fork()瞬间的数据状态,确保RDB一致性
  • 完成持久化
    • 子进程写入完成后,用新RDB替换旧文件,通知主进程
    • 主进程更新持久化状态,释放资源

AOF(append-only file)

简介

AOF(Append Only File,仅追加文件)是 Redis 提供的一种持久化数据的方式。与另一种持久化方式 RDB(Redis Database Backup)不同,AOF 的主要思想是将 Redis 执行的每一条写操作命令追加到一个日志文件中

工作原理

  • 命令追加(Append)
    每个写命令执行后,会以协议文本格式追加到 AOF 缓冲区(内存),随后根据配置策略同步到磁盘的 AOF 文件。
  • 文件同步策略(fsync)
    通过 appendfsync 参数控制同步频率。
    • always:每次写命令后同步,数据安全性最高,但性能最低。
    • everysec(默认):每秒同步一次,平衡安全性与性能,最多丢失 1 秒数据。
    • no:由操作系统决定同步时机,性能最佳,但可能丢失较多数据。
  • 文件重写(Rewrite)
    随着时间推移,AOF 文件会膨胀。重写机制通过生成精简的新文件替换旧文件。
    • 触发方式:手动(BGREWRITEAOF 命令)或自动(根据文件增长比例和最小大小)。
    • 实现原理:基于当前数据库状态生成等效的最简命令集,移除冗余命令(如多次修改同一键)。
    • 子进程处理:重写由子进程完成,避免阻塞主线程,期间新命令会同时写入 AOF 缓冲区。
特性AOFRDB
持久化方式记录每次写命令定期生成数据快照
数据完整性更高(按秒级/实时)较低(依赖快照间隔)
文件大小较大(需重写优化)较小(二进制压缩)
恢复速度较慢(逐条执行命令)更快(直接加载快照)
性能影响高频率同步可能影响吞吐量生成快照时可能短暂阻塞

配置

在 Redis 配置文件(redis.conf)中设置:

开启AOF持久化
shell
appendonly yes               # 启用 AOF
appendfilename "appendonly.aof"  # AOF 文件名
appendfsync everysec         # 同步策略(推荐默认)
开启AOF文件重写
shell
auto-aof-rewrite-percentage 100  # 文件大小增长 100% 时触发
auto-aof-rewrite-min-size 64mb   # 文件最小达到 64MB

AOF优点

  • 数据完整性高:默认最多丢失 1 秒数据。
  • 可读性强:文件以文本格式记录命令,便于人工分析。
  • 灵活策略:支持多种同步策略,适应不同场景。

AOF缺点

  • 文件体积大:相同数据集下,AOF 文件通常比 RDB 大。
  • 恢复速度慢:需逐条执行命令,恢复耗时长。
  • 性能压力:高写入负载下,always 模式可能显著影响吞吐量。

AOF适用场景

  • 数据安全优先
    允许少量数据丢失时,使用 everysec
    严格要求数据不丢失时,选择 always,最多丢失 1 条命令。
  • 兼顾性能与安全:启用混合持久化,快速恢复同时保留细粒度操作。
  • 需审计操作历史:AOF 文件可用于回放和分析写操作。

混合持久化

简介

Redis 混合持久化(RDB-AOF Hybrid Persistence)是 Redis 4.0 引入的重要特性,通过结合 RDB 快照的高效性和 AOF 日志的实时性,实现更优的数据持久化与恢复效率
混合持久化是 Redis 在高性能与数据安全之间权衡的终极方案,配合 appendfsync everysec 和合理的重写阈值,实现性能与安全的平衡。

对比维度混合持久化独立 RDB独立 AOF
数据丢失窗口取决于 AOF 同步策略(如 1 秒)依赖 RDB 快照间隔(如 5 分钟)同混合持久化
恢复速度快(RDB 加载 + 少量 AOF 重放)最快(直接加载 RDB)慢(逐条执行命令)
文件大小较小(RDB 压缩 + 增量 AOF)最小(二进制压缩)最大(文本命令累积)

工作原理

  • AOF 重写时触发混合持久化
    当触发 AOF 重写(手动或自动)时,Redis 会:
    • 生成 RDB 快照:子进程将当前数据库状态以 RDB 二进制格式写入新的 AOF 文件头部(称为 RDB preamble)。
    • 追加增量 AOF 命令:主线程继续接收新写入的命令,以 AOF 文本格式追加到 RDB 数据之后。
    • 替换旧文件:重写完成后,新文件替换旧的 AOF 文件,形成 RDB + AOF 的混合格式。
  • 数据恢复流程
    Redis 重启时:
    • 优先加载 RDB 部分:快速还原数据库快照状态。
    • 执行后续 AOF 命令:按顺序重放 RDB 快照时间点之后的增量命令,确保数据完整性。

配置

混合持久化配置
shell
appendonly yes                  # 必须启用 AOF
aof-use-rdb-preamble yes        # 开启混合模式

TIP

开启混合持久化必先开启AOF持久化