0%

redis持久化

Redis 持久化机制详解:RDB、AOF 与混合模式

Redis 作为内存数据库,数据默认存储在内存中,若发生宕机可能导致数据丢失。持久化机制通过将内存数据写入磁盘,确保数据可恢复。Redis 提供两种核心持久化方式:RDB(快照)AOF(Append Only File),4.0 版本后新增 混合模式,结合两者优势。本文基于 Redis 6.0.10 版本,详细解析这三种机制的原理、配置与优缺点。

RDB 持久化(Redis DataBase)

RDB 是 Redis 默认的持久化方式,通过定时生成内存数据的快照(二进制文件)实现持久化,恢复时通过加载快照文件还原数据。

核心原理

  • 快照生成:在指定时间间隔内,当写入操作满足触发条件时,Redis 会 fork 一个子进程,将内存数据完整写入临时文件,完成后替换旧快照文件(dump.rdb)。

  • Copy On Write(COW)fork 后父子进程共享内存数据,父进程处理新请求时,若修改数据会复制对应内存页(不影响子进程的快照生成),避免数据不一致。

    子进程在做数据持久化的过程中,只会进行遍历读取,但是父进程必须服务客户端请求,可能会对数据进行修改,此时使用COW(copy on write)机制,当父进程写数据时,将该内存页复制一份父进程来操作修改,其余的还是在共享内存内。随着父进程持续的修改数据,越来越多的共享页面被分离出来,内存会持续增长,但是最多也不会超过原有数据内存的2倍

    每一页是4K

配置参数(redis.conf)

RDB 配置位于 SNAPSHOTTING 模块,核心参数如下:

参数 作用 默认值
save <seconds> <changes> 触发快照的条件(多少秒内发生多少次修改),多条件为 “或” 关系。 save 900 1(15 分钟 1 次)、save 300 10(5 分钟 10 次)、save 60 10000(1 分钟 10000 次)
stop-writes-on-bgsave-error 若快照生成失败,是否停止写入操作(避免数据不一致)。 yes
rdbcompression 是否使用 LZF 算法压缩快照文件(节省空间,略增 CPU 开销)。 yes
rdbchecksum 是否对快照文件进行 CRC64 校验(确保完整性,略增性能损耗)。 yes
dbfilename 快照文件名称。 dump.rdb
dir 快照文件存储目录。 /usr/local/var/db/redis/

save 900 1 #15分钟内修改了1次
save 300 10 #5分钟内修改了10次
save 60 10000 #1分钟内修改了10000次

当达到条件时会触发bgsave命令

这个我测试了一下 save 300 3表示的是自上次生成rdb快照后,300s内如果有3次更改,在300s的时间节点时会触发一次bgsave命令,而不是写入3次后就立马触发

手动触发快照

  • save 命令:由主线程执行,会阻塞所有客户端请求(直到快照完成),生产环境慎用
  • bgsave 命令:后台执行(background save),fork 子进程处理快照,主线程继续响应请求,不阻塞服务。

bgsave命令在执行时,服务器处理save、bgsave、bgrewriteaof这三个命令会与平时不同

  • save命令不可执行,避免父子进程同时执行rdbsave,防止产生竞争条件
  • bgsave命令不可执行,防止两个bgsave产生竞争条件
  • 如果此时bgsave正在执行,bgrewriteaof会被延迟到bgsave执行完之后执行;如果bgrewriteaof正在执行,则bgsave命令会被拒绝, 为了防止两个子进程同时执行造成大量的磁盘写入操作
1
2
3
4
5
127.0.0.1:6379> bgsave  # 后台生成快照
Background saving started

127.0.0.1:6379> lastsave # 查看最近一次快照成功的时间戳
(integer) 1690000000

优缺点分析

优点 缺点
快照文件为压缩二进制,体积小,传输 / 恢复高效(适合大规模数据)。 若宕机,可能丢失最后一次快照后的所有数据(依赖触发条件)。
生成快照时由子进程处理,主线程阻塞时间短(仅 fork 瞬间)。 频繁生成快照(如高写入场景)会导致大量磁盘 I/O,影响性能。

动态控制 RDB

1
2
3
4
5
# 关闭 RDB 持久化(清空触发条件)
127.0.0.1:6379> config set save ""

# 查看 RDB 状态
127.0.0.1:6379> config get save # 返回空表示已关闭

AOF 持久化(Append Only File)

AOF 以日志形式记录所有写操作(仅追加,不修改),恢复时通过重新执行日志中的命令还原数据。默认关闭,需手动开启。

核心原理

  • 日志记录:每执行一次写命令(如 sethset),Redis 会将命令追加到 AOF 缓冲区(aof_buf),再定期同步到磁盘文件(appendonly.aof)。
  • 恢复机制:重启时,Redis 会逐条执行 AOF 文件中的命令,重建内存数据。

配置参数(redis.conf)

AOF 配置位于 APPEND ONLY MODE 模块,核心参数如下:

参数 作用 默认值
appendonly 是否开启 AOF 持久化。 no(默认关闭)
appendfilename AOF 文件名。 appendonly.aof
appendfsync 同步策略(控制缓冲区数据写入磁盘的时机): - always:每条命令立即同步(最安全,最慢); - everysec:每秒同步一次(默认,平衡安全与性能); - no:由操作系统决定同步时机(最快,最不安全)。 everysec
no-appendfsync-on-rewrite AOF 重写时是否暂停同步(避免磁盘 I/O 冲突)。
这个配置是指是否在每次fsync的时候都进行重写,但是这样会造成大量的磁盘IO,还有可能会造成对写操作的阻塞,所以一般该值不推荐修改为yes
no(不暂停)
auto-aof-rewrite-percentage 重写触发的增长率(当前 AOF 大小超过上次重写后大小的百分比)。 100(增长 100%)
auto-aof-rewrite-min-size 重写的最小文件大小(避免小文件频繁重写)。 64mb

AOF 重写机制

AOF 日志会随写操作不断追加,导致文件过大。重写机制通过合并冗余命令(如多次修改同一键),生成最小指令集,压缩文件体积。

  • 触发方式
    • 自动触发:当 AOF 文件大小超过 auto-aof-rewrite-min-size 且增长率达到 auto-aof-rewrite-percentage 时。
    • 手动触发:执行 bgrewriteaof 命令。
  • 重写过程
    1. fork 子进程,基于当前内存数据生成精简命令集,写入临时文件。
    2. 父进程将新写命令同时追加到旧 AOF 文件和重写缓冲区。
    3. 子进程完成后,父进程将缓冲区命令追加到临时文件,替换旧 AOF 文件。

AOF 文件修复

若 AOF 文件因宕机损坏(如命令不完整),可使用官方工具修复:

1
redis-check-aof --fix appendonly.aof  # 修复损坏的 AOF 文件

优缺点分析

优点 缺点
数据安全性更高(everysec 策略最多丢失 1 秒数据)。 AOF 文件体积通常远大于 RDB,恢复速度较慢。
日志为文本命令,可手动编辑(如删除误操作的 flushall 命令)。 重写时需消耗大量 CPU / 内存资源。

动态控制 AOF

1
2
3
4
5
# 开启 AOF 持久化
127.0.0.1:6379> config set appendonly yes

# 关闭 AOF 持久化
127.0.0.1:6379> config set appendonly no

混合持久化(RDB + AOF)

Redis 4.0 引入混合模式,结合 RDB 和 AOF 的优势:AOF 文件头部存储 RDB 快照,尾部存储增量 AOF 命令

核心原理

  • 重写时生成混合文件:执行 bgrewriteaof 时,子进程先将内存数据以 RDB 格式写入临时文件,再将重写期间的增量命令以 AOF 格式追加,最终生成混合 AOF 文件。
  • 恢复过程:重启时先加载 RDB 部分(快速恢复大量数据),再执行尾部 AOF 命令(恢复增量数据)。

配置参数

1
aof-use-rdb-preamble yes  # 开启混合模式(默认开启,需先开启 AOF)

优点

  • 恢复速度快:RDB 部分快速加载大量数据,AOF 部分保证增量数据完整性。
  • 文件体积小:RDB 压缩格式减少头部体积,尾部仅记录增量命令,整体比纯 AOF 更小。

持久化方式的选择

场景需求 推荐方式 理由
数据安全性优先(如金融数据) AOF(everysec 最多丢失 1 秒数据,日志可编辑修复。
性能优先(如高写入缓存) RDB 或混合模式 RDB 磁盘 I/O 少,混合模式平衡性能与安全性。
大规模数据备份 / 迁移 RDB 快照文件小,传输高效,恢复速度快。
双保险(关键业务) 混合模式 结合 RDB 的高效与 AOF 的安全性,避免单一机制缺陷。

补充:Redis 定时任务与持久化

Redis 的 serverCron 函数是核心定时任务(由 hz 配置控制执行频率,默认每秒 10 次),负责触发持久化相关操作:

  • 检查 RDB 触发条件,执行 bgsave
  • 检查 AOF 重写条件,执行 bgrewriteaof
  • 处理子进程(RDB/AOF 子进程)的结束信号。

配置 hz 可调整频率(如 hz 20 表示每秒 20 次),更高频率能更快触发持久化,但会增加 CPU 开销

欢迎关注我的其它发布渠道