Redis 持久化机制解析

Redis 持久化机制解析

 次点击
15 分钟阅读

2025-7-15

Redis(Remote Dictionary Server) 是一个开源的、基于内存的数据结构存储系统,通常用作数据库、缓存和消息代理。它支持多种数据类型,如字符串、哈希、列表、集合和有序集合,并提供快速的读写访问速度。Redis将数据存储在内存中,可以快速地进行数据存取,并且可以通过异步方式将数据持久化到磁盘,以防止数据丢失。

Redis 之所以快,是因为Redis在网络上使用了NIO(non-blocking IO)模式,同时是运行在内存中的,相比于磁盘快了很多。也是因为这个特性,当服务器产生异常,例如宕机之后,会导致内存中的信息丢失,影响服务正常运行,因此引出了持久化机制。

Redis提供的持久化分为以下两种
  1. RDB 一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb^1,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。

  2. AOF(Append-only file) AOF会以日志的方式记录客户端对服务器的每一次写操作命令,并将这些写操作以Redis协议追加保存到以后缀为aof文件末尾,在Redis服务器重启时,会加载并运行aof文件的命令,以达到恢复数据的目的

接下来详细介绍这两种持久化方案

1. RDB

主动触发
  1. save 命令: 在Redis中可以通过向服务端发送save命令手动触发,执行时会阻塞Redis直到数据同步完成。生产环境不建议使用。

  2. bgsave 命令: 手动向服务端发送bgsave命令,Redis服务器主进程会forks一个子进程^2 来执行数据同步,在将数据保存到rdb文件之后,子进程会退出。

被动触发(通过配置来触发)

可以在redis.conf中配置如下选项

# 900s内至少达到一条写命令触发RDB
save 900 1
# 300s内至少达到10条写命令触发RDB
save 300 10
# 60s内至少达到10000条写命令触发RDB
save 60 10000

之后在启动服务器时加载配置文件。执行redis-server redis.conf

通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步,触发时间的把控很重要,触发的时间太短,则容易频繁写入,影响服务器性能,太长则会造成数据丢失。因此不建议使用

RDB持久化时Redis会使用rdbSaveObject函数对内存中的数据进行二进制序列化,保存到rdb文件中,进行bgsave时,当主进程在执行修改操作,对应的数据会复制一份,生成副本,然后子进程将这个副本保存到rdb,在这个过程中主进程仍然可以执行修改操作


2. AOF

AOF在Redis中默认是关闭的,可以在配置文件中配置appendonly yes来开启。AOF在向日志文件中写入时,并不是直接写到磁盘中,而是采用追加写的方式放到AOF缓冲区中,再根据配置中的持久策略来将缓冲区的数据同步到磁盘中,持久策略也是在配置文件中进行配置

# 每个写操作都保存到aof文件中,这种策略很安全
# 但是每个写请求都有IO操作,所以也很慢。
appendfsync always
# 默认写入策略,每秒写入一次aof文件,因此,最多可能会丢失1s的数据。
appendfsync everysec
# 服务器不负责写入aof,交由操作系统来处理什么时候写入aof文件。
# 更快,但也是最不安全的选择,不推荐使用
appendfsync everysec 

AOF将客户端的每一个写操作都追加到aof文件末尾,随着时间的推移aof文件会变得非常大。为了解决这个问题,Redis支持aof文件重写,通过重写aof^3,可以生成一个恢复当前数据的最少命令集,Redis也提供了两种重写方式

主动触发

通过向服务端发送bgrewriteaof命令实现,与RDB中的bgsave类似,主进程fork子进程后执行重写

被动触发
# AOF文件夹满足指定值时触发,默认为64MB
auto-aof-rewrite-min-size 64mb
# 当AOF文件大小超过上次重写后的文件大小的百分比时触发 默认为100
auto-aof-rewrite-percentage 100

重写发生的时候,主进程会 fork 出一个子进程,然后子进程与主进程共享 Redis 物理内存,让子进程将这些 Redis 数据写入重写日志。当数据进行重写的时候,如果此时有新的写入命令执行,会由主进程分别写入 AOF 缓冲和 AOF 重写缓冲;AOF 缓冲用于保证此时即使发生宕机了,原来的 AOF 日志也是完整的,可以用于恢复。AOF 重写缓冲用于保证新的 AOF 文件也不会丢失最新的写入操作

如果同时开启两种持久化会优先采用AOF持久化来还原数据,RDB和AOF还可以进行混合持久化(Redis4.0引入)

3. 混合持久化

配置项为 aof-use-rdb-preamble,配置为 yes 时开启混合持久化,在 redis 4 刚引入时,默认是关闭混合持久化的,但是在 redis 5 中默认已经打开了

本质是通过 AOF 后台重写(bgrewriteaof 命令)完成的,不同的是当开启混合持久化时,fork 出的子进程先将当前全量数据以 RDB 方式写入新的 AOF 文件,然后再将 AOF 重写缓冲区的增量命令以 AOF 方式写入到文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。

各种持久化策略的优缺点

RDB

AOF

混合持久化

优点

恢复数据快,RDB文件占用空间小,文件紧凑适合数据备份,使用子进程生成,对Redis服务器性能影响较小

AOF 比 RDB可靠且安全,对服务器性能影响较小,速度比RDB要快,消耗的内存较少,AOF文件发生错误易修复

结合 RDB 和 AOF 的优点, 更快的重写和恢复

缺点

宕机会造成某个时段内数据的丢失;save命令会造成服务器阻塞;如果数据量太大,bgsave在forks子进程时也会发生阻塞,另外,forks子进程会耗费内存

恢复数据的速度比RDB慢,AOF文件占用空间大

AOF 文件里面的 RDB 部分不再是 AOF 格式,可读性差。配置复杂

适用场景

数据安全性要求不高,大数据集,定期备份

数据安全性要求高,频繁的写操作

兼顾性能和数据安全

不论哪种持久化都会或多或少影响redis的性能,对于可丢失的数据不开启持久化的情况下Redis的性能是最优的

[^1]: 二进制文件,默认采用LZF算法进行压缩处理

[^2]: 这个创建子进程的过程也会阻塞Redis

[^3]: 重写策略,1:过期数据不写入文件,2:无效的命令不写入文件,3:合并命令

© 本文著作权归作者所有,未经许可不得转载使用。