news 2026/6/12 0:58:56

Redis 从入门到精通:持久化RDB 与 AOF

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis 从入门到精通:持久化RDB 与 AOF

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。

Redis 以极致的性能著称,核心原因之一就是所有数据都在内存中读写。但内存的特性是易失的——一旦断电或进程崩溃,所有数据瞬间消失。如果 Redis 只做缓存还好,数据丢了可以从数据库重新加载;可当它承载着分布式锁、计数器、消息队列等关键业务数据时,丢数据就是事故。

因此,Redis 提供了两种持久化机制,将内存数据保存到磁盘:RDB(快照)AOF(追加日志),以及它们的结合体——混合持久化。本文带你彻底理解这三种方案的工作原理、配置方法、优缺点和实战策略,让你面对“会不会丢数据”这类问题时从容作答。

1. 为什么需要持久化?

先理清一个概念:持久化不是“备份”,而是数据从内存到磁盘的同步过程。它的价值体现在:

  • 故障恢复:进程崩溃或服务器重启后,能恢复数据,减少损失。

  • 数据迁移:将 RDB/AOF 文件复制到另一台机器,快速恢复整个数据集。

  • 冷备归档:定期保存某一时刻的完整数据快照。

当然,持久化不是免费的——它消耗磁盘 I/O、CPU 和内存,需要在性能数据安全之间做权衡。理解每种方案的原理,才能做出正确选择。

2. RDB(Redis Database)—— 内存快照

2.1 什么是 RDB?

RDB 就是在某个时间点,把 Redis 中所有数据生成一份压缩的二进制快照文件(默认名为dump.rdb),保存到磁盘。

可以把它理解为:给 Redis 内存拍了一张“照片”,这张照片就是当时全部数据的完整拷贝。

2.2 RDB 的触发方式

① 手动触发

# 阻塞主进程,直到保存完成(生产环境禁用)127.0.0.1:6379>SAVE OK# 后台异步保存(推荐)127.0.0.1:6379>BGSAVE Background saving started
  • SAVE:在主进程中执行,保存期间 Redis不能处理任何命令。数据量大时会严重阻塞,绝对不要在生产环境使用。

  • BGSAVE:fork 一个子进程,由子进程负责写入 RDB 文件,主进程继续处理请求。这就是我们日常使用的命令。

② 自动触发(配置文件中设置)

打开redis.conf,你会看到类似这样的配置:

# 格式:save <seconds> <changes># 含义:在 N 秒内,如果至少有 M 个键被修改,就触发一次 BGSAVEsave9001# 900 秒(15分钟)内,至少 1 个键被修改save30010# 300 秒(5分钟)内,至少 10 个键被修改save6010000# 60 秒内,至少 10000 个键被修改

多条规则是关系,满足任意一条就触发。也可以清空save配置来禁用自动 RDB(但BGSAVE手动触发仍有效)。

③ 其他自动触发场景

  • 主从复制时,主节点自动执行BGSAVE生成 RDB 文件发给从节点。

  • 执行SHUTDOWN关闭 Redis 时,如果没有开启 AOF,会自动执行一次SAVE

  • 执行FLUSHALL后,如果配置了自动保存规则,会触发一次 RDB(生成空快照,非常危险)。

2.3 RDB 工作原理(BGSAVE 流程)

主进程 子进程 │ │ ├── fork()──────────────────>(写时复制,共享内存页)│ │ ├── 继续处理客户端命令 ├── 遍历所有数据 │ ├── 写入临时 RDB 文件 │ ├── 完成后,原子重命名为 dump.rdb │ └── 退出 │ │ └── 子进程结束,主进程继续服务

关键点:fork()使用了操作系统的**写时复制(Copy-On-Write)**机制。fork 出的子进程和父进程共享同一块物理内存,只有当父进程修改数据时,操作系统才会把对应的内存页复制一份。这样既保证了子进程能看到 fork 瞬间的完整数据,又不会过度占用内存。

⚠️ 如果 fork 后父进程写入量很大,会导致大量内存页被复制,内存占用可能短时间内翻倍。这也是为什么 Redis 需要预留一半内存的原因之一。

2.4 RDB 配置详解

# redis.conf# RDB 文件名dbfilename dump.rdb# RDB 文件保存路径(需确保 Redis 有写权限)dir/data/redis# 保存规则(前面已介绍)save9001save30010save6010000# 写入错误时是否停止接受写入(建议 yes)stop-writes-on-bgsave-erroryes# 是否压缩 RDB 文件(CPU 换磁盘空间)rdbcompressionyes# 是否对 RDB 文件做完整性校验rdbchecksumyes

Python 中查看持久化配置

importredis r=redis.Redis(decode_responses=True)# 查看 RDB 相关配置forkeyin['dbfilename','dir','rdbcompression','rdbchecksum']: print(f'{key}: {r.config_get(key)[key]}')# 手动触发 BGSAVEresult=r.bgsave()print(f'BGSAVE 是否触发: {result}')# 查看最近一次 BGSAVE 是否成功(返回 Unix 时间戳)last_save=r.lastsave()print(f'上次成功保存时间: {last_save}')

输出示例:

dbfilename: dump.rdb dir: /data rdbcompression:yesrdbchecksum:yesBGSAVE 是否触发: True 上次成功保存时间:1718092800

2.5 RDB 的优缺点

优点

  • 文件紧凑:单一压缩二进制文件,非常适合冷备和灾难恢复。

  • 恢复速度快:直接加载二进制数据到内存,比逐条回放 AOF 快得多。

  • 性能影响小BGSAVE由子进程完成,主进程只负责 fork,不影响正常请求处理。

  • 适合主从同步:主从复制首次全量同步直接传 RDB 文件。

缺点

  • 会丢数据:两次 RDB 之间的数据没来得及持久化,一旦宕机就丢失。

  • 大数据量时 fork 代价高:内存越大,fork 越慢(毫秒到秒级),可能阻塞主进程。

  • 写时复制导致内存压力:频繁写入时,内存占用可能暴涨。

3. AOF(Append Only File)—— 命令日志

3.1 什么是 AOF?

AOF 记录的是每一条修改数据的 Redis 命令(写入、删除、修改),按时间顺序追加到日志文件中。重启时,Redis 通过逐条回放 AOF 中的命令来重建数据。

可以把它理解为:不是给数据拍照,而是记录下了“拍照后发生的每一条改动”。

3.2 AOF 的开启与基本配置

# redis.confappendonlyyes# 开启 AOFappendfilename"appendonly.aof"# AOF 文件名dir/data/redis# 存放目录(与 RDB 共用)

重启 Redis 后,用redis-cli观察:

127.0.0.1:6379>SET name"IT策士"OK127.0.0.1:6379>SET age30OK127.0.0.1:6379>INCR counter(integer)1

查看 AOF 文件内容(通过 Docker 进入容器或直接在服务器上):

$cat/data/appendonly.aof *3$3SET$4name$8IT策士 *3$3SET$3age$230*2$4INCR$7counter

AOF 文件是 Redis 协议格式的纯文本,可读可解析。如果误操作FLUSHALL,还可以手动编辑 AOF 文件删除那条命令然后恢复数据(仅限紧急情况)。

3.3 AOF 写入策略(appendfsync)

Redis 提供三种写入磁盘的策略,由appendfsync配置:

# 每次写命令都同步到磁盘(最安全,但最慢)appendfsync always# 每秒同步一次(默认,性能与安全的最佳平衡)appendfsync everysec# 完全依赖操作系统缓冲区刷新(最快,但可能丢大量数据)appendfsync no

为什么everysec是最佳平衡?

Redis 主线程负责将 AOF 写入内存缓冲区,然后由单独的 AOF 刷盘线程每秒执行一次fsync系统调用,将缓冲区数据真正写入磁盘。主线程不参与实际的磁盘写入,所以对性能影响极小。1 秒的数据丢失窗口,对于绝大多数互联网场景是可接受的。

3.4 AOF 重写(Rewrite)—— 防止文件无限膨胀

AOF 会不断追加命令,文件大小必然持续增长。假设一个计数器INCR了 100 次,AOF 里会有 100 条INCR命令,而实际上恢复数据只需要最后的值。

AOF 重写就是 Redis 自己创建一个新的 AOF 文件,只包含重建当前数据集所需的最少命令。

# 手动触发重写127.0.0.1:6379>BGREWRITEAOF Background append onlyfilerewriting started

自动重写配置

# 当 AOF 文件体积比上次重写后增长了 100%,且超过 64MB 时,自动触发重写auto-aof-rewrite-percentage100auto-aof-rewrite-min-size 64mb

重写流程

主进程 子进程 │ │ ├── fork()──────────────────────>│ │ ├── 读取数据库数据 │ ├── 生成新 AOF 文件(最小命令集) │ └── 退出 ├── 期间的新命令同时写入: │ ├── 旧 AOF 缓冲区(正常 AOF) │ └── AOF 重写缓冲区(记录增量) │ └── 子进程完成后,将重写缓冲区的增量写入新 AOF,然后原子替换旧 AOF

这个过程与 RDB 的BGSAVE非常类似,利用子进程和写时复制,主进程几乎不受影响。

3.5 AOF 相关配置总览

# 开启 AOFappendonlyyes# 文件路径appendfilename"appendonly.aof"# 写入策略appendfsync everysec# 重写期间是否继续同步旧 AOF(yes 保证安全但可能阻塞)no-appendfsync-on-rewrite no# 自动重写触发条件auto-aof-rewrite-percentage100auto-aof-rewrite-min-size 64mb# AOF 文件尾部损坏时,是否允许启动(yes 会忽略尾部错误,尝试恢复)aof-load-truncatedyes

3.6 AOF 的优缺点

优点

  • 数据更安全everysec最多丢 1 秒数据,always完全不丢。

  • 可读性好:AOF 文件是 Redis 协议文本,可直接查看和编辑。

  • 自动重写:防止文件无限增长,保持文件体积可控。

缺点

  • 恢复速度慢:重新回放所有命令,大数据量时远比 RDB 慢。

  • 文件体积大:相同数据集,AOF 文件通常比 RDB 大。

  • 写入性能有损耗:即使everysec,每秒刷盘也会消耗 I/O。

4. 混合持久化 —— Redis 4.0 的最佳方案

既然 RDB 恢复快但可能丢数据,AOF 数据安全但恢复慢,能否鱼与熊掌兼得?Redis 4.0 引入了混合持久化,完美融合了二者的优点。

4.1 混合持久化原理

混合持久化在 AOF 重写时生效。重写出的新 AOF 文件不是纯命令,而是两部分组成

┌─────────────────────────────────────┐ │ RDB 格式的二进制数据 │ ← 重写瞬间的内存快照 │ (占文件前半部分) │ ├─────────────────────────────────────┤ │ AOF 格式的增量命令 │ ← 重写过程中新产生的命令 │ (占文件后半部分) │ └─────────────────────────────────────┘
  • 前半部分是 RDB 格式,包含了重写时刻的全部数据,体积小,加载快。

  • 后半部分是 AOF 命令,记录了重写过程中新增的数据修改。

重启加载时,Redis 先读 RDB 部分快速恢复大部分数据,再回放少量 AOF 增量命令,既快又完整。

4.2 开启混合持久化

# redis.conf(Redis 4.0+ 支持)aof-use-rdb-preambleyes

查看并设置:

127.0.0.1:6379>CONFIG GET aof-use-rdb-preamble1)"aof-use-rdb-preamble"2)"yes"127.0.0.1:6379>CONFIG SET aof-use-rdb-preambleyesOK

Python 中检查和触发 AOF 重写

importredis r=redis.Redis(decode_responses=True)# 查看混合持久化是否开启preamble=r.config_get('aof-use-rdb-preamble')['aof-use-rdb-preamble']print(f'混合持久化: {"开启" if preamble == "yes" else "关闭"}')# 查看 AOF 信息info=r.info('persistence')print(f"AOF 开启: {info['aof_enabled']}")print(f"AOF 当前大小: {info['aof_current_size']} bytes")print(f"AOF 基础大小: {info['aof_base_size']} bytes")# 手动触发 AOF 重写r.bgrewriteaof()print("已触发 BGREWRITEAOF")

4.3 混合持久化的优缺点

优点

  • 恢复速度快:RDB 部分加载快,附加少量 AOF 回放。

  • 数据完整:AOF 增量保证了重写期间的数据不丢失。

  • 文件体积可控:每次重写生成新文件,比纯 AOF 更小。

缺点

  • 可读性降低:文件前部分是二进制,不能直接cat查看。

  • 兼容性:仅 Redis 4.0+ 支持,老版本无法读取混合格式。

💡生产推荐同时开启 RDB 和 AOF,开启混合持久化。这是目前最广泛使用也是最稳妥的方案。

5. 备份恢复策略

5.1 数据备份

无论 RDB 还是 AOF,都应该定期将持久化文件备份到其他存储介质(云存储、NAS、异地机器)。

# 备份 RDB 文件cp/data/redis/dump.rdb /backup/redis/dump_$(date+%Y%m%d_%H%M).rdb# 备份 AOF 文件cp/data/redis/appendonly.aof /backup/redis/aof_$(date+%Y%m%d_%H%M).aof

Python 自动化备份脚本(配合 crontab 定时执行):

importredisimportshutilimportos from datetimeimportdatetime r=redis.Redis(decode_responses=True)# 1. 触发 BGSAVE,确保 RDB 是最新的r.bgsave()# 2. 获取 RDB 文件路径dir_path=r.config_get('dir')['dir']rdb_file=r.config_get('dbfilename')['dbfilename']rdb_path=os.path.join(dir_path, rdb_file)# 3. 备份到指定目录(加上时间戳)backup_dir='/backup/redis'os.makedirs(backup_dir,exist_ok=True)timestamp=datetime.now().strftime('%Y%m%d_%H%M%S')backup_path=os.path.join(backup_dir, f'dump_{timestamp}.rdb')shutil.copy2(rdb_path, backup_path)print(f'备份完成: {backup_path}')print(f'文件大小: {os.path.getsize(backup_path)} bytes')

5.2 数据恢复

恢复流程

  1. 停止 Redis。

  2. 将备份的持久化文件复制到 Redis 数据目录。

  3. 启动 Redis,它会自动加载持久化文件。

# 1. 停止 Redisredis-clishutdown# 或 docker stop redis-lab# 2. 复制备份文件cp/backup/redis/dump_20260101_0300.rdb /data/redis/dump.rdb# 3. 重启 Redisredis-server /etc/redis/redis.conf# 或 docker start redis-lab

⚠️ 如果同时存在dump.rdbappendonly.aof,Redis 优先加载 AOF 文件(因为它通常数据更完整)。

5.3 AOF 文件修复

如果 AOF 文件损坏导致 Redis 无法启动:

# Redis 自带修复工具redis-check-aof--fixappendonly.aof

它会截断 AOF 文件到最后一个有效命令处,舍弃尾部损坏部分。

6. 实战:Docker 环境配置持久化

用 Docker 启动一个开启了 RDB + AOF + 混合持久化的 Redis:

# 创建本地目录用于挂载mkdir-p~/redis-data# 启动容器dockerrun-d\--nameredis-persist\-p6379:6379\-v~/redis-data:/data\redis:7.2 redis-server\--appendonlyyes\--appendfsynceverysec\--aof-use-rdb-preambleyes\--save9001\--save30010\--save6010000

验证:

# 进入容器dockerexec-itredis-persist redis-cli127.0.0.1:6379>CONFIG GET appendonly1)"appendonly"2)"yes"127.0.0.1:6379>CONFIG GET aof-use-rdb-preamble1)"aof-use-rdb-preamble"2)"yes"# 写一些数据127.0.0.1:6379>SETtest"persistence"OK# 查看持久化文件# 在宿主机:ls -lh ~/redis-data/

7. 选型决策树

你的 Redis 用途是什么? │ ├── 纯缓存(数据可重建) │ └── 关掉所有持久化,性能极致 │ ├── 一般业务(允许丢1分钟数据) │ └── 只开 RDB,配置 save 规则 │ ├── 重要业务(最多丢1秒) │ └── 开 AOF everysec,定期 BGREWRITEAOF │ └── 核心业务(几乎不能丢数据) ├── RDB + AOF everysec ├── 开启混合持久化 └── 配合主从 + 定期异地备份

8. 动手试试

  1. 体验 RDB:开启 Redis,设置save 60 1,写入若干键,等待 60 秒观察dump.rdb的生成时间和大小。模拟宕机(docker restart),检查数据是否恢复。

  2. 体验 AOF 重写:循环写入 10 万条SET,查看appendonly.aof文件大小。手动执行BGREWRITEAOF,对比重写前后的文件大小。

  3. 混合持久化对比:分别用纯 AOF 和混合持久化方式写入同样的数据,重写后对比文件大小和redis-benchmark恢复速度。

  4. 模拟恢复:删除 Redis 容器并重新创建,挂载之前的持久化文件,验证数据是否完整恢复。

预期效果:RDB 快照恢复后丢失快照后写入的数据;AOF 恢复完整但慢;混合持久化恢复快且数据完整。

9. 总结

本文我们深入了 Redis 持久化三大方案:

核心要点:

  • RDB 是“拍照”,AOF 是“录像”,混合是“先拍照再录像”。

  • everysec是 AOF 写入策略的甜点。

  • Redis 4.0+ 一律开启混合持久化。

  • 持久化文件要异地备份,并定期演练恢复。

持久化是 Redis 数据安全的基石。掌握了它,你就懂得了如何在性能和安全之间游刃有余地取舍。下一章,我们将进入 Redis 高可用架构的第一站——主从复制,看如何通过多副本提高数据安全和读吞吐量。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 0:57:11

CHZZK完整指南:解锁Naver直播生态的Node.js神器

CHZZK完整指南&#xff1a;解锁Naver直播生态的Node.js神器 【免费下载链接】chzzk 네이버 라이브 스트리밍 서비스 치지직의 비공식 API 라이브러리 项目地址: https://gitcode.com/gh_mirrors/ch/chzzk 在当今直播行业蓬勃发展的时代&#xff0c;开发者需要一个强大而…

作者头像 李华
网站建设 2026/6/12 0:54:01

MC9S08SH8 TPM模块深度解析:从输入捕获到PWM的实战指南

1. 项目概述&#xff1a;深入理解MCU的“心跳”与“脉搏”在嵌入式系统的世界里&#xff0c;微控制器&#xff08;MCU&#xff09;的“心跳”通常由系统时钟决定&#xff0c;而它的“脉搏”——那些精准的定时、对外部事件的快速响应、以及生成复杂控制波形的能力——则往往依赖…

作者头像 李华
网站建设 2026/6/12 0:51:54

【课程设计/毕业设计】基于SpringBoot的婚纱影楼服务平台设计和实现摄影师管理、套餐类型管理、婚纱套餐管理、套餐预定管理、拍摄预约管理【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/12 0:49:03

发现新多晶型吲哚美辛

- - 由Rigaku参与的联合研究成果发表于《晶体生长与设计》 -Rigaku Corporation是X射线分析系统的全球解决方案合作伙伴&#xff0c;并隶属Rigaku Holdings Corporation&#xff08;总部&#xff1a;东京都昭岛市&#xff1b; CEO&#xff1a;Jun Kawakami&#xff1b;以下简称…

作者头像 李华