Skip to content

redis 数据持久化

Redis 提供两种主流持久化:RDB(Redis Database,快照)与 AOF(Append Only File,命令日志);4.0 起支持混合持久化(AOF 重写时前导为 RDB 格式,后续为增量命令,兼顾恢复速度与数据安全)。

持久化的作用

Redis 是基于内存的数据库,数据默认存储在内存中,一旦进程退出或服务器宕机,数据会丢失。 因此,持久化是 Redis 保证数据可靠性的核心机制,其目的是将内存中的数据定期或实时同步到磁盘,以便在重启后恢复数据。

RDB 持久化(快照持久化)

RDB 是 Redis 默认的持久化方式,原理是在指定时间间隔内,将内存中的完整数据集生成快照(二进制文件)并写入磁盘。

shell
# 核心原理
RDB 通过 “快照” 机制工作:Redis 会在满足触发条件时,将当前内存中的所有数据以二进制形式写入磁盘文件(默认名为 dump.rdb)。
 Redis 重启时,会读取该文件并将数据加载到内存中,恢复到快照生成时的状态。

# RDB 的触发分为手动触发和自动触发:
## 手动触发(通过执行命令主动生成 RDB 快照)
save:由主线程直接执行快照生成,期间会阻塞所有客户端请求(不推荐在生产环境使用,可能导致服务卡顿)。
bgsave:主线程会 fork 一个子进程,由子进程负责生成快照,主线程继续处理客户端请求(无阻塞,推荐使用)。

## 自动触发
通过配置文件 redis.conf 中的 save 指令定义触发条件(格式:save <seconds> <changes>),表示 “在 seconds 秒内发生至少 changes 次数据修改时,自动触发 bgsave”。

## 示例(只要满足任一条件,就会触发 RDB 快照)
save 900 1    # 900秒内有1次修改
save 300 10   # 300秒内有10次修改
save 60 10000 # 60秒内有10000次修改

## RDB 文件细节
默认路径:由配置 dir ./ 指定(默认当前目录),文件名由 dbfilename dump.rdb 指定。
存储格式:二进制(紧凑、体积小),仅包含数据本身,不包含命令。

## 优点
快照文件体积小,适合备份(例如每日凌晨生成 RDB 并归档)。
恢复速度快:加载 RDB 文件时直接解析二进制数据到内存,无需执行命令,效率远高于 AOF。
对主线程影响小:bgsave 通过子进程生成快照,不阻塞服务。

## 缺点
数据安全性低:RDB “间隔性快照”,如果在两次快照之间宕机,期间的新数据会丢失(例如配置 save 60 10000 时,最坏可能丢失 60 秒数据)。
fork 子进程成本高:bgsave fork 操作会复制主线程的内存页表(虽然是 “写时复制”,但数据量大时仍可能阻塞主线程毫秒级甚至秒级)。

AOF 持久化(日志持久化)

AOF 是另一种持久化方式,原理是将所有写命令(如 set、hmset 等)以文本形式追加到日志文件中,重启时通过重新执行文件中的所有命令恢复数据。

shell
# 核心原理
Redis 执行写命令后,会将命令追加到 AOF 缓冲区,再根据配置的同步策略将缓冲区内容写入磁盘文件(默认名为 appendonly.aof)。
重启时,Redis 会逐行读取 AOF 文件中的命令并执行,最终恢复数据。

# 开启方式(AOF 默认关闭,需在 redis.conf 中配置开启)
appendonly yes  # 开启AOF

# 同步策略(数据安全性与性能的平衡)
AOF 的关键是 “何时将缓冲区内容写入磁盘”,由 appendfsync 配置控制,有三种策略:
appendfsync always:每次写命令执行后立即调用 fsync(强制刷盘),数据安全性最高(仅丢失当前命令),但频繁 IO 操作会导致性能极低(不推荐生产环境)。
appendfsync everysec:每秒调用一次 fsync,平衡安全性和性能(最多丢失 1 秒数据),是默认且推荐的配置。
appendfsync no:不主动刷盘,由操作系统决定何时写入磁盘(可能延迟几秒),性能最好但安全性最低(宕机可能丢失大量数据)。

# AOF 重写(解决文件膨胀问题)
AOF 会记录所有写命令,长期运行后文件会越来越大(例如多次 incr counter 会记录成多条命令),导致恢复速度慢且占用磁盘空间。因此,Redis 提供了AOF 重写机制,通过 “合并命令” 压缩文件。
## 重写原理
根据当前内存中的数据,生成最精简的命令(例如将 100 incr counter 合并为 set counter 100),替换旧的 AOF 文件。
## 触发方式
手动触发:执行 bgrewriteaof 命令(类似 bgsave,fork 子进程处理,不阻塞主线程)。
自动触发:通过配置 auto-aof-rewrite-percentage auto-aof-rewrite-min-size 控制
auto-aof-rewrite-percentage 100  # 当前AOF文件大小比上次重写后大100%时触发
auto-aof-rewrite-min-size 64mb   # AOF文件至少达到64MB才可能触发重写

# 优点
数据安全性高:everysec 策略下最多丢失 1 秒数据,远优于 RDB 的间隔快照。
日志文件是文本形式,可读性强(可手动修改错误命令)。

# 缺点
文件体积大:即使经过重写,AOF 文件通常也比 RDB 大。
恢复速度慢:重启时需要重新执行所有命令,数据量大时恢复时间长。
重写成本高:bgrewriteaof fork 操作同样可能阻塞主线程。

混合持久化(RDB + AOF)

Redis 4.0 引入了混合持久化,结合了 RDB 和 AOF 的优势:AOF 文件的开头是 RDB 格式的快照,后续是增量的 AOF 命令。

shell
# 核心原理
混合持久化开启后,AOF 重写时不再生成纯命令的 AOF 文件,而是:
先将当前内存数据以 RDB 格式写入 AOF 文件开头;
再将重写期间的新命令以 AOF 格式追加到后面。
重启时,Redis 会先加载 RDB 部分快速恢复大部分数据,再执行后续的 AOF 命令恢复增量数据

# 开启方式
 redis.conf 中配置:
aof-use-rdb-preamble yes  # 混合持久化:4.0+ 支持;是否默认开启以你安装的 redis.conf 为准(常见发行版多为 yes)

# 优点
恢复速度快:结合 RDB 快速加载和 AOF 增量恢复的优势。
数据安全性高:增量命令部分保证了低数据丢失风险。
文件体积适中:比纯 AOF 小,比 RDB 稍大。

# 缺点
兼容性略差:老版本 Redis 不支持混合格式的 AOF 文件。

三者对比

shell
特性       RDB           AOF             混合持久化
存储内容     二进制快照     文本命令日志     RDB 快照 + AOF 命令
恢复速度             较快
数据安全性 低(丢失间隔数据) 高(最多丢 1 秒)
文件体积
性能影响     低(间隔性 fork) 中(每秒 fsync)

持久化方案选择

优先 RDB:适合数据量大、可容忍几分钟数据丢失(如缓存场景),追求快速备份和恢复。

优先 AOF:适合对数据安全性要求高(如金融场景),可接受稍慢的恢复速度。

混合持久化:多数场景下兼顾安全性与恢复速度;以实际 redis.conf 与版本说明为准,勿死记「某版本必默认开」。