Redis持久化
Redis 持久化是确保数据安全的关键机制,它能将内存中的数据保存到磁盘,防止服务重启或宕机时数据丢失。
1、RDB(Redis Database)持久化:定时快照
RDB 持久化是在指定的时间间隔内,生成内存中整个数据集的一个快照(Snapshot),并将其保存到一个二进制文件中(默认文件名为 dump.rdb)。
1.1 工作原理
触发机制:当满足配置的条件时(如 900秒内至少有1个key被修改),Redis会fork一个子进程(共享内存页)。
子进程工作:子进程拥有父进程内存数据的拷贝。它负责将整个数据集序列化并写入到一个临时的RDB文件中。
替换旧文件:当子进程完成写临时文件后,会用这个新文件替换旧的 RDB 文件。
关键点:fork操作是同步的,可能会阻塞主进程,但实际的数据写入由子进程完成,主进程不会进行任何磁盘 I/O 操作,可以继续处理客户端命令。
1.2 配置文件
在 redis.conf 中配置快照触发条件
# 含义:seconds 内发生 changes 次数据修改,则触发快照
# 在900秒(15分钟)内,如果至少有1个key发生变化,则触发bgsave
save 900 1
# 在300秒(5分钟)内,如果至少有10个key发生变化,则触发bgsave
save 300 10
# 在60秒内,如果至少有10000个key发生变化,则触发bgsave
save 60 10000
# 满足任一条件即自动执行 bgsave
# 如果持久化出错,是否停止接收写操作(推荐yes,保证数据一致性)
stop-writes-on-bgsave-error yes
# 是否对RDB文件进行LZF压缩(推荐yes,压缩后文件更小,但会消耗少量CPU)
rdbcompression yes
# RDB文件名
dbfilename dump.rdb
# RDB文件保存目录
dir ./
1.3 触发方式
- 自动触发(配置文件控制)
- 手动触发
SAVE:阻塞 Redis 主进程,直到 RDB 生成完成(不建议生产环境使用,会导致服务不可用)。
BGSAVE:后台异步生成 RDB,主进程继续处理命令(推荐使用)。
2、AOF(Append Only File)持久化:写操作日志
AOF 通过记录每一个写操作命令(读操作不记录)到日志文件来实现持久化。Redis 重启时会重新执行这些命令来恢复数据
2.1 工作原理
- 日志追加:每执行一条写命令,Redis 会将该命令以 Redis 协议格式追加到 AOF 文件的末尾(先写入内核的 OS Buffer)。
- 文件同步 (fsync):根据配置的策略,将 OS Buffer 中的内容同步(fsync) 到磁盘上的 AOF 文件。
- 重启恢复:Redis 重启时,会创建一个伪客户端,从头到尾重新执行一遍 AOF 文件中的所有命令,从而重建内存数据。
2.2 配置文件
# 开启AOF持久化(默认是no)
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# AOF文件同步策略
# appendfsync always # 每次写命令都同步到磁盘(最安全,性能最差)
appendfsync everysec # 每秒同步一次(默认,平衡安全与性能)
# appendfsync no # 由操作系统决定何时同步(性能最好,安全性最差)
# 在AOF重写期间,是否禁止fsync(推荐no,保证数据安全)
no-appendfsync-on-rewrite no
# 触发AOF重写的条件(两个条件需要同时满足)
auto-aof-rewrite-percentage 100 # 当前AOF文件比上次重写后大了100%
auto-aof-rewrite-min-size 64mb # 且当前AOF文件大小至少是64MB
# 加载AOF文件时,如果文件末尾被截断(可能由于系统崩溃),是否继续(推荐yes)
aof-load-truncated yes
2.3 AOF 重写(解决文件膨胀)
AOF 会不断追加命令,导致文件越来越大(如 INCR count 执行 1000 次,AOF 会记录 1000 条命令)。AOF 重写通过合并命令(如将 1000 次 INCR 合并为 SET count 1000),压缩文件体积。
触发方式:
- 自动触发:通过配置文件设置重写条件
# 触发AOF重写的条件(两个条件需要同时满足)
auto-aof-rewrite-percentage 100 # 当前AOF文件比上次重写后大了100%
auto-aof-rewrite-min-size 64mb # 且当前AOF文件大小至少是64MB
- 手动触发:执行 BGREWRITEAOF 命令,后台异步重写:
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
重写流程
- 主进程 fork 子进程,子进程基于当前内存数据生成新 AOF 文件(合并命令)。
- 主进程继续处理命令,同时将新命令写入缓冲区和旧 AOF 文件。
- 子进程重写完成后,主进程将缓冲区命令追加到新 AOF 文件,然后替换旧文件。
3、最佳实践-混合持久化 (RDB + AOF)
Redis 4.0 之后支持混合持久化,结合了 RDB 和 AOF 的优点
工作原理
- 当执行 BGREWRITEAOF 时,子进程不再是像以前一样将内存数据转换为命令写入 AOF。
- 而是先将内存数据以 RDB 的格式写入到新的 AOF 文件的开头。
- 然后,再将重写缓冲区(在重写期间,主进程仍在接收命令,这些命令会同时写入到现有的 AOF 缓冲区和重写缓冲区)内的所有增量命令以 AOF 格式追加到 RDB 数据的后面。
- 最终生成的新 AOF 文件是一个前半段是 RDB 二进制格式,后半段是 AOF 命令文本格式的混合文件。
开启方式:
# 必须同时开启AOF
aof-use-rdb-preamble yes
3、最佳实践
最佳实践redis持久化配置:
# 默认情况下,Redis 会异步将数据集转储到磁盘上。
# 你可以根据需求设置保存策略,格式为:save <seconds> <changes>
# 在指定的秒数内,如果发生了指定数量的写操作,则保存一次快照。
# 可以设置多个保存条件。
save 900 1 # 900秒(15分钟)内至少有1个key发生变化
save 300 10 # 300秒(5分钟)内至少有10个key发生变化
save 60 10000 # 60秒内至少有10000个key发生变化
# 如果持久化出错,是否停止接收写操作(推荐yes,保证数据一致性)
stop-writes-on-bgsave-error yes
# 是否对RDB文件进行LZF压缩(推荐yes,压缩后文件更小,但会消耗少量CPU)
rdbcompression yes
# 从Redis 5.0开始,可以使用CRC64算法进行RDB文件校验
rdbchecksum yes
# RDB文件名
dbfilename dump.rdb
# RDB文件和工作目录(AOF文件也会创建在这里)
dir /var/lib/redis
# 开启AOF持久化(默认是no)
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# AOF文件同步策略:
# always: 每个写命令都同步,数据最安全但性能最差
# everysec: 每秒同步一次,是安全性和性能的折中方案(推荐)
# no: 由操作系统决定何时同步,性能最好但数据最不安全
appendfsync everysec
# 在AOF重写期间,是否禁止fsync
# 如果设置为yes,可以提高重写性能,但可能丢失最多30秒的数据
# 如果设置为no,则数据最安全,但重写期间可能会有一些延迟
no-appendfsync-on-rewrite no
# 触发AOF重写的条件(两个条件需要同时满足)
# 当前AOF文件比上次重写后大了指定的百分比
auto-aof-rewrite-percentage 100
# 且当前AOF文件大小至少达到指定值
auto-aof-rewrite-min-size 64mb
# 加载AOF文件时,如果文件末尾被截断(可能由于系统崩溃),是否继续
aof-load-truncated yes
# 开启混合持久化(Redis 4.0+)
# 重写AOF文件时,先生成RDB格式的数据,再将增量命令以AOF格式追加
aof-use-rdb-preamble yes
# 当Redis启动时,如果AOF文件存在,则优先加载AOF文件来恢复数据
aof-load-truncated yes
4、总结
Redis 持久化是保证数据可靠性的核心机制:
- RDB 适合备份和快速恢复,牺牲实时性换取性能。
- AOF 适合高安全性场景,通过命令日志实现秒级数据保护。
- 生产环境推荐 RDB + AOF 结合,兼顾安全性和备份需求,同时做好监控和定期备份,避免单点故障导致数据丢失。
浙公网安备 33010602011771号