大家好,这里是Good Note,关注 公主号:Goodnote,专栏文章私信限时Free。本文详细介绍Redis的持久化机制,目标是将内存中的数据持久化到磁盘,以保证数据的可靠性和在重启后的恢复能力。
文章目录
- 持久化机制
- AOF(Append-Only File)
- 配置
- 原理
- 触发方式
- AOF 文件重写
- 优点
- 缺点
- AOF流程
- 写入流程
- 重写流程(AOF 重写)
- RDB(Redis Database Snapshot)
- 配置
- 原理
- 触发方式
- 优点
- 缺点
- RDB流程
- 生成流程
- 加载流程
- AOF 和 RDB 的对比
- 混合持久化(Hybrid Persistence)
- 混合持久化的工作原理
- 配置混合持久化
- 混合持久化的文件结构
- 优点和缺点
- 适用场景
- 混合文件的恢复流程
- 1. 加载 RDB 部分
- 2. 回放 AOF 部分
- 数据恢复
- 性能优化与实践建议
- 历史文章
- MySQL数据库
- Redis
持久化机制
Redis 提供了三种持久化机制:RDB(Redis Database Snapshot) 、AOF(Append Only File)以及二者结合的混合持久化,以及一种混合模式(Hybrid Persistence)。这些机制的目标是将内存中的数据持久化到磁盘,以保证数据的可靠性和在重启后的恢复能力。
- RDB:在指定的时间间隔能对你的数据进行快照存储。
- AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
- 混合持久化:在 Redis 4.0 引入,通过结合 RDB 和 AOF 的特性,既保留 RDB 的高效性,又降低 AOF 文件大小和启动时间。
Redis 默认的持久化机制取决于 Redis 的配置,但通常情况下,Redis 默认启用了 RDB 持久化,并且没有开启 AOF 持久化,除非修改了配置文件。如果同时配置了AOF 和 RDB 持久化,则会优先使用AOF。
AOF(Append-Only File)
配置
# 是否开启 AOF
appendonly yes# AOF 文件名称
appendfilename "appendonly.aof"# 数据同步策略
appendfsync everysec# 重写期间是否同步
no-appendfsync-on-rewrite no# 重写触发条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb# 加载 AOF 出错时的处理策略
aof-load-truncated yes# 文件重写增量同步
aof-rewrite-incremental-fsync yes
appendfsync
策略:always
:每个命令都同步到磁盘,最安全但最慢。everysec
:每秒同步一次,性能与安全的折中方案(推荐)。no
:由操作系统决定同步时间,最快但最不安全。
- 重写触发条件:
- AOF 文件大小超过上一次重写时的 100% 且大于 64 MB 时触发。
- 重要选项:
aof-load-truncated
:AOF 文件尾部损坏时是否继续加载数据。
原理
- Redis 会将每个写命令以文本形式追加到 AOF 文件(默认名为
appendonly.aof
)中。 - 根据配置的
fsync
策略,定期将数据同步到磁盘,以确保持久化。
触发方式
- 持久化频率由
appendfsync
参数决定:always
:每次写命令都立即同步到磁盘,数据最安全但性能最差。everysec
(默认):每秒同步一次,数据丢失量较小,性能较好。no
:让操作系统决定何时将数据写入磁盘,性能最高,但数据丢失风险大。
一般情况下都采用 everysec 配置,这样可以兼顾速度与安全,最多损失1s的数据。
AOF 文件重写
- 随着时间推移,AOF 文件会变得越来越大,AOF重写是为了减少aof文件的大小。
- Redis 支持文件重写(rewrite),通过对当前内存数据生成最简化的命令集,重新写入 AOF 文件,减少文件体积,如移除冗余命令、过时命令未清理等。
- 触发方式:
- 自动触发:基于配置的大小增长比例触发。
auto-aof-rewrite-min-size 64mb # 文件大小超过 64MB 时触发
auto-aof-rewrite-percentage 100 # 文件体积增长超过 100% 时触发
- 手动触发:执行
BGREWRITEAOF
。该命令在后台执行,重新生成 AOF 文件。
- 自动触发:基于配置的大小增长比例触发。
优点
- 数据安全性高
默认每秒执行一次fsync
操作,即使服务器意外崩溃,最多只丢失 1 秒数据。 - 写入性能高
追加操作直接写入文件尾部,性能较优。 - 文本格式,便于编辑和恢复,方便AOF重写
AOF 文件是文本格式,兼容性好、追加方便、可读性高,便于编辑和恢复。例如,执行错误命令(如flushall
)后,可通过编辑日志文件移除相关命令恢复数据。
缺点
- 文件体积大
同等数据量下,AOF 文件通常比 RDB 文件更大。 - 性能开销较高
每次写命令都需记录,性能开销比 RDB 大;不过 AOF 重写功能可以优化文件大小。 - 恢复速度慢
由于需要重放所有日志命令,数据恢复耗时较长,不适合冷备场景。
AOF流程
写入流程
-
命令追加:
- Redis 将每个写操作(如
SET
、DEL
等)以文本形式追加到 AOF 文件末尾。 - 命令以 Redis 协议格式保存,确保可解析和回放。
- Redis 将每个写操作(如
-
同步到磁盘:
- 根据
appendfsync
参数设置,AOF 数据会以不同频率同步到磁盘:- always:每次写入都同步,数据安全性最高,但性能较差。
- everysec:每秒同步一次,性能和安全性折中(默认)。
- no:由操作系统决定何时同步,性能最高,但可能丢失数据。
- 根据
重写流程(AOF 重写)
-
触发条件:
- 手动触发:使用命令
BGREWRITEAOF
。 - 自动触发:AOF 文件增长到一定比例时触发(由
auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
参数控制)。
- 手动触发:使用命令
-
后台子进程创建新文件:
- Redis 创建子进程,扫描当前内存数据,生成最简化的命令集,写入新的 AOF 文件。
- 新文件不会包含冗余命令,只保存当前内存数据的最小状态。
-
替换旧文件:
- 新文件生成后,替换旧的 AOF 文件,同时追加在重写期间产生的写操作。
RDB(Redis Database Snapshot)
配置
# 保存规则:时间间隔和写入操作次数
save 900 1
save 300 10
save 60 10000# RDB 文件名称与存储路径
dbfilename dump.rdb
dir /home/work/app/redis/data/# 持久化出错时是否停止写入
stop-writes-on-bgsave-error yes# 启用压缩
rdbcompression yes# 导入时校验文件
rdbchecksum yes
save
规则:save 900 1
表示 900 秒内至少 1 次写操作触发快照。- 配置多条规则,是为了适配不同的业务高峰和低谷,平衡性能与数据安全。
- 重要选项:
stop-writes-on-bgsave-error
:备份出错时停止写入,避免数据不一致。- 禁用 RDB:可通过配置
save ""
。
原理
- 定期将内存中的所有数据以二进制形式保存为
.rdb
文件。 - 使用
fork
子进程完成备份操作,不影响主进程服务。
触发方式
-
自动触发:
- 通过
save
指令设置触发条件。例如:save 900 1 # 在 900 秒内有至少 1 次写操作时触发保存 save 300 10 # 在 300 秒内有至少 10 次写操作时触发保存 save 60 10000 # 在 60 秒内有至少 10000 次写操作时触发保存
- 通过
-
手动触发:
SAVE
:阻塞式保存快照,会暂停所有客户端操作直到完成,耗时较长,线上应该禁止使用。BGSAVE
:异步保存快照,在后台执行,不阻塞 Redis 服务。该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。
-
异常触发:
- 当 Redis 关闭时,如果启用了快照,RDB 文件会自动生成。
优点
- 快速恢复
适合大规模数据的恢复,文件加载速度快。 - 低影响
fork
子进程处理备份,主进程性能影响较小。
缺点
- 可能丢失数据
例如每 5 分钟备份一次,若在备份周期内崩溃,可能丢失近 5 分钟数据。 - 潜在停顿
数据量大时,fork
操作会导致 Redis 短暂阻塞。
RDB流程
生成流程
-
触发快照:
- 手动触发:使用命令
SAVE
或BGSAVE
。 - 自动触发:根据配置的
save
参数(如save 60 1000
表示 60 秒内有 1000 次修改)触发。
- 手动触发:使用命令
-
后台子进程保存数据:
- Redis fork 一个子进程,子进程从内存中读取所有数据并写入临时 RDB 文件。
- 主进程继续处理客户端请求,不阻塞。
-
文件替换:
- 临时 RDB 文件写入完成后,替换旧的 RDB 文件。
加载流程
- Redis 启动时,如果配置了 RDB 文件路径,优先加载 RDB 文件以恢复数据。
AOF 和 RDB 的对比
特性 | AOF(追加日志) | RDB(快照) |
---|---|---|
持久化频率 | 可控(always/everysec/no) | 定期生成(按配置的 save 参数) |
数据安全性 | 更高,丢失数据量小(取决于同步策略) | 较低,可能丢失最近一次快照后的数据 |
文件体积 | 文件较大,包含所有写操作记录(重复和冗余) | 文件较小,仅保存数据的二进制快照 |
恢复速度 | 较慢,需要回放所有写操作记录 | 较快,直接加载快照 |
性能影响 | 持续追加日志,性能开销较高 | 定期保存快照,瞬时性能开销大 |
适用场景 | 数据安全要求高,写操作频繁的场景 | 数据安全要求低,恢复速度要求高的场景 |
混合持久化(Hybrid Persistence)
混合持久化是 Redis 4.0 引入的一种持久化机制,混合持久化通过结合 RDB 和 AOF 的特性,既保留 RDB 的高效性,又降低 AOF 文件大小和启动时间。
混合持久化的工作原理
在混合持久化模式下,Redis 在执行持久化时:
- 生成 RDB 快照:
- 将内存中的数据快照保存到 RDB 文件。
- 追加增量 AOF 日志:
- 在 RDB 快照之后,记录从快照生成到持久化完成之间的所有操作日志。
- 混合文件的恢复:
- 恢复时,Redis 先加载 RDB 部分的数据,再应用 AOF 部分的增量日志,以恢复到最新状态。
混合文件同时具备 RDB 和 AOF 的优点:
- 恢复速度快:先加载二进制格式的 RDB 快照。
- 数据更完整:通过 AOF 增量日志弥补最新数据。
配置混合持久化
混合持久化默认启用,可以通过以下配置项调整:
aof-use-rdb-preamble yes
yes
(默认值):启用混合持久化,AOF 文件以 RDB 数据为开头。no
:禁用混合持久化,AOF 文件完全基于操作日志。
混合持久化的文件结构
混合持久化生成的 AOF 文件结构:
- 前半部分:RDB 格式,存储数据快照。
- 后半部分:AOF 格式,存储增量日志。
例如:
+-------------------+---------------------+
| RDB 快照内容 | 增量 AOF 操作日志 |
+-------------------+---------------------+
Redis 在恢复时:
- 加载 RDB 内容:快速加载二进制快照数据。
- 回放 AOF 日志:应用操作日志更新到最新状态。
优点和缺点
优点:
- 启动速度更快:加载 RDB 格式的数据比逐条执行 AOF 日志更高效。
- 数据更完整:通过增量日志减少数据丢失的可能性。
- 文件体积小:相比纯 AOF,文件大小更小。
缺点:
- 复杂性增加:持久化过程需要同时管理 RDB 和 AOF。
- 写性能略低:混合持久化时需要在持久化阶段生成快照和日志。
适用场景
- 需要 快速恢复 的场景(如大规模数据集)。
- 低延迟的写操作 和 高数据可靠性 并重的场景。
- 适合既对启动时间敏感,又需要减少数据丢失的应用。
混合文件的恢复流程
在 Redis 中,混合持久化的 AOF 文件由两部分组成:
- RDB 部分:存储生成快照时的数据(内存快照)。
- AOF 部分:记录从快照生成到持久化完成之间的增量日志(操作日志)。
混合文件在恢复时,通过以下步骤恢复到最新状态:
1. 加载 RDB 部分
-
文件结构:
- 混合持久化的 AOF 文件以 RDB 格式开头。
- RDB 格式是一种二进制格式,包含 Redis 数据结构(如字符串、哈希、列表等)的序列化数据。
-
加载过程:
- Redis 检测到 AOF 文件开头是 RDB 格式。
- 使用与普通 RDB 文件相同的逻辑解析和加载二进制数据。
- 将快照中的数据完整恢复到内存中。
-
恢复特点:
- 该阶段相当于加载普通 RDB 文件,加载速度较快。
- 数据恢复到快照生成时的状态。
2. 回放 AOF 部分
-
文件结构:
- AOF 部分紧随 RDB 部分之后,存储的是以 Redis 通用协议(RESP)表示的增量操作日志。
- 这些操作日志记录了从 RDB 快照生成到 AOF 持久化完成之间发生的写操作。
-
回放过程:
- Redis 开始解析 AOF 文件的后半部分(增量日志)。
- 按顺序逐条执行 AOF 部分的命令。
- 如
SET
、LPUSH
、HSET
等操作。
- 如
- 将这些操作作用于内存数据,逐步将内存状态更新到最新。
-
恢复特点:
- AOF 部分的回放确保快照生成后发生的修改不会丢失。
- 恢复速度较慢,但可以避免丢失增量数据。
数据恢复
Redis 会优先加载 AOF 文件(数据更完整,AOF基本上最多损失1s的数据。),若无 AOF 文件则加载 RDB。
性能优化与实践建议
- 降低阻塞影响
- 控制最大内存,减少
fork
时间。 - 手动触发备份和重写,避免多实例同时进行持久化操作。
- 控制最大内存,减少
- 主从配合
- 主机提供服务,从机用于备份,分摊性能压力。
- 混合使用
- 同时启用 RDB 和 AOF,以满足快速恢复和数据安全的双重需求。
历史文章
MySQL数据库
- MySQL数据库笔记——数据库三范式
- MySQL数据库笔记——存储引擎(InnoDB、MyISAM、MEMORY、ARCHIVE)
- MySQL数据库笔记——常见的几种锁分类
- MySQL数据库笔记——索引介绍
- MySQL数据库笔记——事务介绍
- MySQL数据库笔记——索引结构之B+树
- MySQL数据库笔记——索引潜规则(回表查询、索引覆盖、索引下推)
- MySQL数据库笔记——索引潜规则(最左前缀原则)
- MySQL数据库笔记——常见慢查询优化方式
- MySQL数据库笔记——日志介绍
- MySQL数据库笔记——多版本并发控制MVCC
- MySQL数据库笔记——主从复制
Redis
- Redis数据库笔记——数据结构类型
- Redis数据库——Redis雪崩、穿透、击穿
- Redis数据库——内存淘汰机制
- Redis数据库笔记——内存分配器
- Redis数据库笔记——内存预分配
- Redis数据库笔记—— Hash(哈希)的扩容机制(rehash)
- Redis数据库笔记——ZSet的底层实现(跳表)
- Redis数据库笔记——布隆过滤器(BloomFilter)