持久化与数据可靠性
RDB(快照)
简介
Redis 的 RDB(Redis Database Backup) 是一种基于快照的持久化机制,用于将内存中的数据集在某个时间点的状态保存到磁盘文件中(默认文件名为 dump.rdb)。
RDB 通过生成二进制压缩文件的方式持久化数据,其优势在于高效、紧凑和快速恢复,适合对数据一致性要求不苛刻的场景(允许少量数据丢失)。在实际应用中,通常结合业务需求调整快照触发频率,或与 AOF 持久化配合使用,以平衡性能和数据安全性。
工作原理
- 快照生成
RDB 通过创建数据快照来实现持久化。
快照生成时,Redis 会将内存中的所有数据以二进制格式写入磁盘文件。 - 触发方式
- 手动触发
- save命令:阻塞主进程,客户端请求(包括读和写)都会被阻塞,直到快照生成完成。
- bgsave命令(推荐):后台异步生成快照,Redis 会 fork 一个子进程执行持久化操作,主进程继续处理其它请求。
- 自动触发 根据 redis.conf 中的配置规则自动触发 bgsave,满足任一条件时,自动触发快照。shell
save 900 1 # 900秒(15分钟)内至少1个键被修改 save 300 10 # 300秒(5分钟)内至少10个键被修改 save 60 10000 # 60秒内至少10000个键被修改
- 手动触发
配置
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 yesRDB 优点
- 紧凑高效 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 缓冲区。
| 特性 | AOF | RDB |
|---|---|---|
| 持久化方式 | 记录每次写命令 | 定期生成数据快照 |
| 数据完整性 | 更高(按秒级/实时) | 较低(依赖快照间隔) |
| 文件大小 | 较大(需重写优化) | 较小(二进制压缩) |
| 恢复速度 | 较慢(逐条执行命令) | 更快(直接加载快照) |
| 性能影响 | 高频率同步可能影响吞吐量 | 生成快照时可能短暂阻塞 |
配置
在 Redis 配置文件(redis.conf)中设置:
shell
appendonly yes # 启用 AOF
appendfilename "appendonly.aof" # AOF 文件名
appendfsync everysec # 同步策略(推荐默认)shell
auto-aof-rewrite-percentage 100 # 文件大小增长 100% 时触发
auto-aof-rewrite-min-size 64mb # 文件最小达到 64MBAOF优点
- 数据完整性高:默认最多丢失 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持久化
