一文搞懂 Redis 的 持久化机制

Redis 支持的 持久化机制 有三种:

  • RDB(Redis DataBase)持久化
  • AOF(Append Only File)持久化
  • RDB-AOF 混合持久化

1、RDB(Redis DataBase)

  • Redis 默认采用的持久化机制
  • 以 快照 的形式将进程数据持久化到硬盘中
  • 会生成一个经过 压缩 的二进制文件(文件后缀为 .rdb)
  • 文件内部存储了 各个数据库的 键值对数据

 注:Redis 默认有 16 个数据库,分别是 DB0 ~ DB15



持久化的触发方式:

  • 手动触发:通过 save / bgsave 命令 触发持久化操作
  • 自动触发:通过配置选项,让服务器在满足指定条件时自动执行 bgsave 命令

​ 注:RDB 保存的默认文件是 dump.rdb

在这里插入图片描述



save 与 bgsave 命令的比较

  • save 命令 采用同步的方式 :使用 Redis 服务器进程 进行 “.rdb” 文件的创建,命令执行期间 Redis 服务器将一直处于阻塞状态
  • bgsave 命令 采用异步的方式:使用 Redis 服务器进程 的 子进程进行 “.rdb” 文件的创建,只有在创建 子进程 时 Redis 服务器才会处于阻塞状态,创建完毕之后便脱离阻塞状态

​ 注:由于 save 命令存在的阻塞问题,目前 save 命令 已被废弃



bgsave 命令的执行流程:

  1. 若父进程存在正在执行的子进程,直接返回
  2. fork 操作(创建子进程) 执行过程中,父进程进入阻塞状态
  3. fork 操作 完成后,父进程继续响应其他命令
  4. 创建 “.rdb” 文件,并存储 父进程内存中的数据
  5. 父进程 得到通知,以新的 “.rdb” 文件 替换旧的 “.rdb” 文件

在这里插入图片描述


bgsave 命令的原理:COW(Copy On Write)

  • 在 Linux 操作系统中,可以通过 glibc库 中的 fork 函数 创建一个子进程,该进程与父进程完全相同,并且共享 父进程 的内存空间
  • 当 父进程 或 子进程 需要修改内存中的数据时,会将对应的 page 进行复制,然后对副本进行修改

在这里插入图片描述


RDB 的优缺点:

  • 优点:生成的二进制文件体积小,恢复数据的速度快
  • 缺点:bgsave 命令每次执行时都会 创建子进程(属于重量级操作),资源消耗大

​ 补充:由于 创建子进程 时,Redis 服务器进程 会阻塞一段时间,因而 RDB持久化 没办法做到实时的持久化。




2、AOF(Append Only File)

  • 目前 Redis 持久化 的主流方式(解决了数据持久化的实时性)
  • 以 独立日志 的方式,记录了每次写入的命令
  • 生成一个 文本协议格式 的 文本文件(文件后缀为 “.aof”)

AOF 默认不开启,需要修改配置项来启动它:

appendonly yes						# 启动 aof
appendfilename "appendonly.aof"		# 设置文件名

 注:AOF 保存的默认文件是 appendonly.aof



AOF 的工作流程:

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

在这里插入图片描述


补充:

 AOF 以 文本协议格式 写入命令,如:

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

 文本协议格式的优点:

  • 良好的兼容性
  • 避免二次处理的开销
  • 可读性高,方便直接修改和处理


AOF 的 文件同步机制:

  • 为了提高程序的写入性能,现代操作系统会把针对硬盘的多次写操作优化为一次写操作
    • 当程序调用 write 对文件写入时,系统不会直接将数据写入硬盘,而是先将数据写入到 内存的数据缓存区 中;当 数据缓存区 写满时 或 达到一定的 时间周期 时,系统才会执行 flush 操作,将 数据缓存区 的全部数据 一次性写入硬盘
  • 这种优化机制虽然提高了性能,但同时也给程序的写入操作带来了不确定性
    • 当 内存掉电 而 还没进行 flush 操作 时,数据缓存区的数据会直接全部丢失
  • 为了减小这种不确定性带来后果,Redis 向用户提供了 appendfsync 选项,用来控制系统 冲洗(flush) AOF文件 的频率
    • appendfsync 基于 Linux 操作系统中 glibc库 中的 fsync函数,该函数可以将指定文件强制从数据缓冲区 冲洗 到硬盘上

补充:appendfsync 选项的取值 和 含义

取值说明
always每执行一个写入命令,就对 AOF文件 执行一次冲洗操作
在这种情况下,服务器在停机时最多丢失一个命令,但同时会大大降低服务器的性能
everysec每隔1秒,就对 AOF文件 执行一次冲洗操作
在这种情况下,服务器在停机时最多丢失1秒之内的命令,是一种兼顾性能和安全性的折中方案
no不主动对 AOF文件执行冲洗操作,由操作系统决定何时冲洗
在这种情况下,服务器在停机时将丢失最后一次冲洗后执行的命令,数据量取决于系统的冲洗频率


AOF 的优缺点:

  • 优点:相较 RDB(一旦 内存掉电,存在于内存的数据全部丢失),AOF 丢失数据的量更小,而通过 everysec 选项,用户可以将数据丢失的时间窗口限制在1秒之内。

  • 缺点:

    • AOF文件 存储的是 协议格式文本,其体积 相较于 RDB 的二进制文件 大很多
    • 当需要恢复较多数据时,使用 AOF文件 恢复的速度会比较慢(原因在于:需要重新执行每一条命令)
    • AOF 在进行重写时也需要创建 子进程,当数据量较大时将占用较多资源,同时会导致服务器处于短暂阻塞状态


3、RDB-AOF 混合模式

  • 基于 AOF 、结合 RDB 的优点 进行构建

  • 执行 AOF 重写操作时

    • 执行 bgsave 命令生成 RDB数据,并将其写入 AOF文件 中
    • 对于重写之后执行的命令,则以 协议文本 的方式追加到 AOF文件 的末尾(即 RDB数据 之后)
  • 混合模式拥有 AOF、RDB 两者的优点

    • 服务器可以通过 AOF文件 包含的 RDB数据 来实现快速的数据恢复
    • 服务器可以通过 AOF文件 包含的 AOF数据 来将丢失数据的时间窗口限制在1秒之内
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐