文章目录Redis的持久化一、概述1. 为什么Redis要持久化2. 如何实现Redis的持久化3. Redis持久化解决了什么问题二、RDB1. 什么是RDB2. 触发机制1save命令2bgsave命令3自动触发机制3. bgsave命令的运行流程4. RDB 的优缺点总结三、AOF1. 什么是AOF2. AOF的工作流程3. AOF的同步频率设置4. 重写机制5. 触发方式与参数配置6. AOF重写流程四、启动时数据恢复五、小结Redis的持久化一、概述1. 为什么Redis要持久化Redis作为内存数据库断电或宕机易致数据丢失需持久化保障可靠性。2. 如何实现Redis的持久化通过RDB定时快照恢复快、适合备份与AOF追加写日志安全性高两种模式落盘3. Redis持久化解决了什么问题解决了数据易失性问题兼顾了快速恢复与高数据安全二、RDB1. 什么是RDBRDBRedis Database Backup file是Redis默认的持久化机制其核心思想是在指定的时间间隔内将内存中的全量数据生成一个紧凑的二进制快照文件默认名为dump.rdb并保存到磁盘上。2. 触发机制1save命令阻塞当前Redis服务器直到RDB过程完成为止对于内存比较大的实例造成长时间的阻塞基本不采用。2bgsave命令Redis进程执行fork操作创建子进程RDB持久化过程由子进程负责完成后自动结束。阻塞只发生在fork阶段一般时间很短。Redis内部的所有涉及RDB的操作都采用类似的bgsave的方式3自动触发机制① 使用save配置save m n表示在m秒内进行了n次修改自动RDB持久化。② 从节点进行全量复制操作时主节点自动进行RDB持久化随后将RDB文件内容发送给从节点。③ 执行shutdown命令关闭Redis时执行RDB持久化。3. bgsave命令的运行流程1检查并拦截并发任务当 Redis 父进程接收到bgsave命令后首先会检查当前是否已经存在正在执行的持久化子进程如 RDB 或 AOF 重写子进程。如果存在父进程会直接返回错误信息拒绝本次请求如果不存在则继续执行下一步。2Fork创建子进程父进程执行fork()操作创建一个子进程。在这个fork阶段父进程会处于短暂的阻塞状态。当内存数据量极其庞大时这个操作会消耗较多的 CPU 资源甚至可能导致主线程出现秒级的卡顿。fork完成后父进程会向客户端返回 “Background saving started” 信息随后解除阻塞继续正常响应其他客户端请求。3子进程生成快照与写时复制子进程创建成功后开始将内存中的数据写入一个临时的 RDB 文件。此时子进程与父进程共享同一块物理内存。为了防止数据不一致底层依赖了操作系统的写时复制技术Copy-On-Write, COW读操作如果父进程对数据进行读操作父子进程互不影响共同读取同一块物理内存。写操作如果父进程收到客户端的写命令需要修改某块数据操作系统会将该数据的物理内存页复制出一份副本。父进程在副本上进行修改而子进程继续读取原本的内存数据来写入 RDB 文件。4原子替换与信号通知子进程完成临时 RDB 文件的写入后会对原有的 RDB 文件进行原子替换即用新文件安全地覆盖旧文件。随后子进程向父进程发送完成信号并自动结束退出。5父进程更新统计信息父进程接收到子进程的完成信号后会更新相关的统计信息例如最后一次生成 RDB 的时间rdb_last_save_time以及写时复制期间消耗的内存等整个bgsave流程至此圆满结束。4. RDB 的优缺点总结优点文件紧凑适合备份与灾备RDB 是一个单一、紧凑压缩的二进制文件代表了某个时间点的数据快照。它非常适合用于全量复制、灾难恢复等场景例如定期将 RDB 文件传输到远程存储或 HDFS。数据恢复速度快相比于 AOF 需要逐条重放命令Redis 直接加载 RDB 文件来恢复数据的效率要高得多。缺点无法做到实时/秒级持久化由于每次生成 RDB 都需要执行fork创建子进程这是一个相对“重量级”的操作。如果频繁执行例如每秒一次系统开销过大因此通常只能做到分钟级的数据保存存在数据丢失风险。版本兼容性风险RDB 使用特定的二进制格式存储。随着 Redis 版本的演进RDB 格式可能会发生变化旧版本的 Redis 可能无法加载新版本生成的 RDB 文件。三、AOF1. 什么是AOFAOFAppend Only File是 Redis 的另一种持久化机制其核心思想是将每一个写操作命令以追加的方式记录到一个日志文件中。当 Redis 重启时它会重新执行这个文件中的所有命令从而重建内存中的数据。2. AOF的工作流程所有的写入命令会追加到aof_buf缓冲区中AOF缓冲区根据对应的策略向硬盘中做同步操作随着AOF文件越来越大需定期对AOF文件进行重写达到压缩的目的当Redis服务器启动时可以加载AOF文件进行数据恢复3. AOF的同步频率设置Redis 通过appendfsync参数控制 AOF 的刷盘频率有三种模式always每次写命令都立即同步到磁盘最安全但性能最低。everysec默认推荐每秒同步一次兼顾性能与安全最多丢失一秒数据。no由操作系统决定何时刷盘性能最高但风险最大。4. 重写机制随着 Redis 持续运行AOF 文件会因不断追加写命令而变得臃肿。为了解决这个问题Redis 引入了AOF 重写机制。它的核心原理不是读取旧文件进行压缩而是直接读取当前内存中的数据状态将其转化为对应的写命令并同步到新的 AOF 文件中。为什么重写后文件会变小重写后的 AOF 文件体积通常会显著减小主要得益于以下三个“瘦身”策略剔除过期数据内存中已经过期或被淘汰的数据在重写时会被直接忽略不再写入新文件。合并无效命令旧的 AOF 文件中包含的中间状态命令如对同一个 Key 的多次修改、删除操作DEL、HDEL、SREM等会被剔除只保留数据的最终有效版本。批量合并指令多条连续的写操作会被合并为一条更高效的命令。例如连续执行三次LPUSH list a、LPUSH list b、LPUSH list c在重写后会合并为一条LPUSH list a b c5. 触发方式与参数配置AOF 重写支持手动触发和自动触发两种模式手动触发通过客户端调用BGREWRITEAOF命令立即启动后台重写进程。自动触发由 Redis 服务器根据以下两个配置参数自动判断是否满足触发条件auto-aof-rewrite-min-size含义允许触发重写的 AOF 文件最小体积阈值。默认值64MB。如果文件小于此值即使增长比例很高也不会触发。auto-aof-rewrite-percentage含义当前 AOF 文件大小相比上一次重写后大小的增长比例。逻辑当(当前大小 - 上次重写后大小) / 上次重写后大小 设定百分比时触发。6. AOF重写流程发起重写请求若当前进程正在执行 AOF 重写则本次请求不执行。若当前进程正在执行 bgsave 操作则重写命令延迟至 bgsave 完成后再执行。父进程执行 fork 创建子进程。重写过程a. 主进程在 fork 之后继续响应其他命令。所有修改操作写入 AOF 缓冲区并根据 appendfsync 策略同步到硬盘以保证旧 AOF 文件机制正确。b. 子进程仅拥有 fork 之前的内存信息父进程需将 fork 之后的修改操作写入 AOF 重写缓冲区。子进程根据内存快照将命令合并到新的 AOF 文件中。子进程完成重写a. 新文件写入完成后子进程发送信号通知父进程。b. 父进程将 AOF 重写缓冲区内临时保存的命令追加到新 AOF 文件中。c. 使用新 AOF 文件替换旧 AOF 文件。四、启动时数据恢复五、小结Redis 提供了两种持久化方案RDB 和 AOF。RDB 视为内存的快照产生的内容更为紧凑占用空间较小恢复时速度更快。但产生 RDB 的开销较大不适合进行实时持久化一般用于冷备和主从复制。AOF 视为对修改命令保存在恢复时需要重放命令。并且有重写机制来定期压缩 AOF 文件。RDB 和 AOF 都使用 fork 创建子进程利用 Linux 子进程拥有父进程内存快照的特点进行持久化尽可能不影响主进程继续处理后续命令。