redis学习笔记(九)—— Redis 持久化

持久化

redis 使用内存来存储数据,而随着进程退出,内存中的数据也就丢失了;

Redis 支持 RDB 和 AOF 两种持久化机制,持久化有效避免因进程退出造成数据丢失问题;当下次重启时,通过之前的持久化文件实现数据的恢复

日常使用中如果 Redis 进程持续稳定运行,数据不会因进程退出丢失;但一旦进程异常退出或服务器宕机,内存数据仍会丢失,因此需要持久化保障。

RDB

RDB 持久化机制,是定期将当前进程数据生成 快照 保存到硬盘当中;RDB 持久化的触发方式确实核心分为手动触发自动触发

手动触发

可以通过执行 save 和 bgsave 来执行 RDB 持久化

  • save:阻塞当前 Redis 服务器,直到 RDB 完成为止。
  • bgsave:Redis 进程通过 fork 创建子进程,RDB 持久化过程又子进程负责,Redis 进程依旧可以处理客户端命令

自动触发

Redis 运行自动触发 RDB 持久化机制:

  • save 配置:在配置文件中,'save m n' 表示在 m 秒内数据集发生了 n 次修改,自动触发 RDB持久化。
  • 从节点进行 全量复制 时,主节点自动进行 RDB 持久化,然后将 RDB 文件发送给从节点。
  • 执行 shutdown 关闭 Redis 时,也会执行 RDB 持久化。

bgsave 执行流程

  1. 执行 bgsave 命令,Redis父进程判断是否存在其他正在执行的子进程(RDB/AOF),如果存在 bgsave 直接返回
  2. Redis 父进程执行 fork 创建子进程;(fork 过程中父进程会阻塞,通过 info stats 命令可以查看 latest_fork_usec 选项,获取最近一次 fork 操作的耗时,单位 微秒)
  3. Redis 父进程 fork 创建完子进程后,bgsave 命令返回 'Background saving stared'并不再阻塞父进程,Redis可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存数据生成临时快照文件,完成后替换原有的 RDB 文件。
  5. 子进程完成后,通过信号通知 Redis 父进程,父进程 就会回收子进程资源、更新持久化状态。

了解了 bgsave 可以发现,在子进程执行 RDB 持久化过程当中,父进程是可以响应其他命令的;

那Redis 父进程 fork 创建子进程之后、子进程完成 RDB持久化之前,这一段时间的数据,子进程生成的RDB文件中是没有的。

存在写时拷贝机制,子进程执行 RDB 持久化,保存的就是 父进程 fork 时刻的数据

RDB文件

  • RDB 持久化文件默认保存在 dir 配置指定的目录下,Redis 默认路径为 /var/lib/redis/,而具体的文件名则由 dbfilename 参数控制,默认为 dump.rdb
  • 可以在 Redis 运行期间通过 config set dir {newDir}config set dbfilename {newFilename} 动态修改存储目录与文件名,修改后的配置会在下一次执行 RDB 持久化时生效。
  • 需要注意的是,仅通过 config set 修改属于临时配置,重启后会恢复原值,若想永久保留修改,需要同步更新配置文件并执行重写操作。

AOF

AOF 持久化:以独立日志的方式记录每次写命令,重启时重新执行AOF 文件中的命令,而且达到恢复数据的效果。

AOF 主要作用就是解决数据持久化的实时性。

  • 开启 AOF 功能,需要设置配置:appendonly yes(默认不开启)
  • AOF 文件名通过 appendfilename 来设置(默认是 appendonly.aof)。
  • AOF 文件保存目录同 RDB 持久化一致,通过 dir 配置指定。

AOF的工作流程

命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)

  1. 客户端所有写入命令执行后,都会先追加到 aof_buf AOF 缓冲区中。
  2. AOF 缓冲区会按照配置的同步策略,将命令刷写到硬盘上的 AOF 文件中。
  3. 随着运行时间增长,AOF 文件会越来越大,Redis 会定期对 AOF 文件进行重写,以压缩体积、去除冗余命令。
  4. Redis 服务器重启时,会加载并执行 AOF 文件中的所有写命令,以此完成数据恢复。

命令写入

AOF 日志记录的是Redis 执行的写命令 ,格式是 Redis 文本协议(RESP)

  • 命令:set hello world
  • AOF 写入内容:*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

为什么必须要有 aof_buf 缓冲区?

因为 Redis 是单线程工作模型,磁盘 I/O 速度远慢于内存操作,如果没有 aof_buf 内存缓冲区,每执行一条写命令就直接同步磁盘,会导致线程频繁阻塞、I/O 次数剧增,Redis 性能会从内存级大幅下降到磁盘级;而 aof_buf 可以先将命令暂存在内存中,批量刷入磁盘以减少 I/O 次数,同时支持多种同步策略,让性能与数据安全性达到平衡,保证 Redis 高并发处理能力。

文件同步

Redis 先将命令暂存在 aof_buf 缓冲区当中,来减少磁盘 I/O 次数。

Redis 提供了多种 AOF 缓冲区同步机制,通过 appendfsync 来控制:

可配置值 同步逻辑
always 命令写入 aof_buf 后立即调用 fsync 同步,完成后返回
everysec 写入 aof_buf 后只做 write,由后台线程每秒 fsync 一次
no 写入 aof_buf 后只做 write,fsync 完全由操作系统控制

write 和 fsync 的区别

  • write :write 写入操作系统内核缓冲区后立即返回,不会直接将数据落盘,不产生阻塞,但数据未真正持久化,系统宕机存在丢失风险,安全性较低。
  • fsync :fsync 强制将数据从内核缓冲区刷写到硬盘,直到写入完成才返回,会产生阻塞,但能保证数据真正持久化,系统宕机也不会丢失,安全性极高。

AOF重写

随着命令不断的写入 AOF 文件,文件会越来越大;Redis 为解决之一问题,通过了文件压缩机制,将内存中的最终数据重新说生成一份更小的 AOF 文件,替代原有的 AOF 文件。

  • 忽略已过期数据:不再将进程内已超时失效的数据写入新文件。
  • 剔除无效命令:删除旧 AOF 中冗余、无效的命令,只保留数据的最终状态。
  • 合并多条命令:将多次执行的同类写命令合并成一条,减少命令数量。

AOF 重写触发机制

  • 手动触发 :执行 BGREWRITEAOF 命令
  • 自动触发 :配置参数控制自动重写的条件
    1. auto-aof-rewrite-min-size : 表示触发 AOF 重写的最小文件大小
    2. auto-aof-rewrite-percentage : 表示触发 AOF 重写,当前 AOF 文件比上次重写后增长的百分比

AOF 重写流程

  1. 执行 AOF 重写请求

    如果当前进程正在执行 AOF 重写,则直接返回;如果正在执行 bgsave 操作,则将重写命令延迟到 bgsave 完成后再执行。

  2. 父进程执行 fork 创建子进程

  3. 重写过程

    • 父进程 fork 后继续正常处理客户端命令;所有写操作都会写入 AOF 缓冲区,并根据 appendfsync 策略同步到磁盘,保证原有 AOF 文件数据正确。
    • 子进程只包含父进程 fork 之前的内存数据;fork 之后父进程产生的所有修改操作,会额外写入 AOF 重写缓冲区
  4. 子进程生成新 AOF 文件

    子进程根据自身持有的内存快照,对命令进行精简合并,生成新的 AOF 文件。

  5. 完成重写并替换文件

    • 子进程完成新 AOF 文件写入后,通过信号通知父进程。
    • 父进程将 AOF 重写缓冲区中的增量数据追加到新 AOF 文件末尾。
    • 使用新 AOF 文件原子替换旧 AOF 文件,AOF 重写完成。

总结

  1. RDB 总结

RDB 是 Redis 的"快照式"持久化机制,核心是定期将内存数据生成二进制快照文件(dump.rdb),依赖 fork 子进程完成持久化,不阻塞主进程(bgsave 方式)。其核心优势是文件体积小、恢复速度快,适合用于备份、全量复制场景;缺点是数据持久化实时性低,可能丢失两次快照之间的所有数据。

  1. AOF 总结

AOF 是 Redis 的"日志式"持久化机制,核心是实时记录所有写命令到文本日志文件(appendonly.aof),依赖缓冲区和同步策略平衡性能与安全性。其核心优势是数据持久化实时性高(可配置 everysec/always),数据丢失风险极低;缺点是文件体积大、恢复速度慢,重写过程需消耗系统资源。

RDB 和 AOF的区别

对比维度 RDB AOF
持久化方式 快照式,定期生成内存数据的二进制副本 日志式,实时记录所有写命令(文本协议格式)
数据安全性 较低,可能丢失两次快照间的所有数据(取决于 save 配置) 较高,可配置(always 无丢失、everysec 最多丢1秒数据)
文件体积 小(二进制压缩,仅保留最终数据) 大(文本命令,包含冗余操作,需重写压缩)
恢复速度 快(直接加载二进制快照,无需执行命令) 慢(需逐条执行日志中的写命令)
性能影响 低(fork 子进程后,主进程无阻塞,仅 fork 瞬间短暂阻塞) 中(需频繁写入缓冲区、同步磁盘,同步策略越严格,性能影响越大)
触发方式 手动(save、bgsave)、自动(save 配置、全量复制、shutdown) 手动(BGREWRITEAOF)、自动(基于文件大小和增长百分比)
适用场景 备份、全量复制、允许少量数据丢失的场景 对数据安全性要求高、不允许大量数据丢失的场景
文件可读性 差(二进制文件,无法直接查看) 好(文本文件,可直接查看、编辑写命令)

本篇文章到这里就结束了,感谢支持

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

相关推荐
小陈项目管理PMP2 小时前
2026年6月PMP考试:70天冲刺,这5个“备考误区”正在偷偷浪费你的时间
学习·项目管理·pmp
山楂树の2 小时前
【计算机系统原理】 直接映射(模映射) Cache 地址划分与访问过程
学习·缓存
呆子也有梦2 小时前
redis 的延时双删、双重检查锁定在游戏服务端的使用(伪代码为C#)
redis·后端·游戏·缓存·c#
网络工程小王3 小时前
【Python数据分析基础】
大数据·数据库·人工智能·学习
GDAL3 小时前
BoltDB vs Redis 读性能对比:实测表现与原理差异
redis·boltdb
FluxMelodySun3 小时前
机器学习(二十七) 降维:度量学习与随机梯度下降法求解
人工智能·学习·机器学习
busideyang3 小时前
函数指针类型定义笔记
c语言·笔记·stm32·单片机·算法·嵌入式
一尘之中3 小时前
利用QPanda测试量子系统噪声:从理论到QAOA实践
学习·ai写作·量子计算
艾莉丝努力练剑3 小时前
【MYSQL】MYSQL学习的一大重点:表的约束
linux·运维·服务器·开发语言·数据库·学习·mysql