掘金 后端 ( ) • 2024-04-17 22:09

highlight: a11y-dark theme: juejin

Redis ⽀持 RDB 和 AOF 两种持久化机制,Redis 4.0 之后又新增了混合持久化的方式。持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利用之前持久化的⽂件即可实现数据恢复。

1.RDB 持久化

RDB 持久化是把当前进程数据⽣成快照保存到硬盘的过程,触发 RDB 持久化过程分为⼿动触发和⾃动触发。

1.1 触发

⼿动触发分别对应savebgsave命令:

  1. save命令:阻塞当前Redis服务器,直到RDB过程完成为⽌,当内存⽐较⼤的时候可能造成⻓时间阻塞。

image-20240417184452896

  1. bgsave命令:Redis进程执⾏fork操作创建⼦进程,RDB持久化过程由⼦进程负责,完成后⾃动结束。

image-20240417184441652

image-20240417190532767

fork() 操作在Linux中是用于创建一个新的进程的系统调用,并且子进程的创建是对父进程的复制。参考了Linux进程 | fork()系统调用详解 - 掘金 (juejin.cn)

自动触发的情况:

  1. 在配置文件中redis.conf,配置 save,如"save m n"表⽰ m 秒内数据集发⽣了 n 次修改,⾃动RDB持久化。

image-20240417184217337

  1. 执⾏shutdown命令关闭Redis时,执⾏RDB持久化。
shutdown save

1.2 RDB 文件的处理

持久化的数据是默认保存在“/var/lib/redis/”下,文件名可以通过 dbfilename 指定。

image-20240417185444048

可以通过执⾏config set dir{newDir}config set dbfilename{newFilename}运⾏期间动态执⾏,当下次运⾏时RDB⽂件会保存到新⽬录。

Redis默认采⽤LZF算法对⽣成的RDB⽂件做压缩处理,压缩后的⽂件远远⼩于内存⼤⼩,默认开启,可以通过参数config set rdbcompression{yes|no} 动态修改。

image-20240417185718585

1.3 RDB 优缺点

  • 优点:
    • 性能高效:RDB持久化是将内存中的数据以二进制形式保存到硬盘上,因此在持久化过程中不需要进行额外的序列化和反序列化操作,具有很高的性能。
    • 恢复速度快:因为 RDB 文件是一个完整的数据库快照,所以在 Redis 重启后,可以非常快速地将数据恢复到内存中。
  • 缺点:
    • 数据可能丢失:RDB持久化是间隔一定时间进行的,如果Redis意外崩溃,会导致最后一次持久化之后的数据丢失。
    • 不适合实时备份RDB⽅式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运⾏都要执⾏fork创建⼦进程,属于重量级操作,频繁执⾏成本过⾼。

2.AOF 持久化

AOF持久化:以独⽴⽇志的⽅式记录每次写命令,重启时再重新执⾏AOF⽂件中的命令达到恢复数据的⽬的。AOF的主要作⽤是解决了数据持久化的实时性

2.1 开启 AOF

  1. 在配置文件中设置,appendonly yes,默认是不开启的。

image-20240417193051405

  • 流程

image-20240417194516818

  1. 所有的写⼊命令会追加到缓冲区中。
  2. AOF 缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件进⾏重写,达到压缩的⽬的。
  4. 当 Redis 服务器启动时,可以加载 AOF ⽂件进⾏数据恢复。

AOF 为什么需要缓冲区?如果每次写 AOF ⽂件都直接同步硬盘,性能从内存的读写变成 IO 读写,必然会下降。先写⼊缓冲区可以有效减少 IO 次数。

2.2 AOF缓冲区同步⽂件策略

可以在配置文件中设置文件同步策略。

image-20240417195508861

  • 一共有三种策略
    • always:每次写入缓冲区后直接写入 AOF 文件中。
    • everysec(默认):写入缓冲区后,不进行同步。一秒后再进行写入 AOF 文件。
    • no:只执行 write 操作(也就是只缓存),由操作系统控制写入 AOF 文件的频率。

2.3 重写机制

随着命令不断写⼊ AOF,⽂件会越来越⼤,当达到一定的程度后,Redis 会重写文件,减少文件的体积。

  • AOF重写过程可以⼿动触发和⾃动触发:
    • 手动:调⽤bgrewriteaof命令。
    • 自动:在配置文件中
      • auto-aof-rewrite-min-size:表⽰触发重写时AOF的最⼩⽂件⼤⼩,默认为64MB。
      • auto-aof-rewrite-percentage:代表当前AOF占⽤⼤⼩相⽐较上次重写时增加的⽐例。

image-20240417201815379

  • 重写流程

image-20240417205234622

  1. 父进程执行 fork 创建子进程后。
  2. 重写
    1. 主进程 fork 后,继续响应其它命令。所有修改操作写入 AOF 缓冲区,并根据同步策略同步到硬盘,来保证旧 AOF 文件机制的正确。
    2. ⼦进程只有 fork 之前的所有内存信息,⽗进程中需要将 fork 之后这段时间的修改操作写⼊ AOF 重写缓冲区中
  3. ⼦进程根据内存快照,将命令合并到新的 AOF ⽂件中(这里跟 RDB 有点相似)。
  4. 子进程完成重写
    1. 新⽂件写⼊后,⼦进程发送信号给⽗进程。
    2. ⽗进程把 AOF 重写缓冲区内 临时保存的命令追加到新AOF⽂件中。
    3. ⽤新AOF⽂件替换⽼AOF⽂件。

2.4 AOF 的优缺点

  • 优点
    • 实时性好:由于 AOF 持久化方式是将每一个写命名记录到文件中,因此实时性比 RDB 更好。
    • 可读性高:AOF 文件是一个纯文本文件,可以被人类读取和理解。
  • 缺点
    • 写入性能略低:由于 AOF 持久化方式需要将每一个写命令记录到文件中,因此相对于 RDB 持久化方式,它的写入性能略低。
    • 占用磁盘空间大:由于 AOF 持久化方式需要记录每一个写命令,因此相对于 RDB 持久化方式,它占用的磁盘空间更大。

3.混合模式持久化

在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。

image-20240417215009418

3.1 开启混合持久化

  1. 在配置文件中如下设置:

image-20240417210744726

3.2 混合持久化的优缺点

  • 优点

    • 混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,又减低了大量数据丢失的风险。
  • 缺点

    • 可读性差:AOF 文件中添加了 RDB 格式的内容,就让 AOF 文件的可读性变得很差。
    • 兼容性差:如果开启混合持久化,那么此混合持久化 AOF 文件,就不能用在 Redis 4.0 之前版本了。

4.启动恢复数据的流程

  1. 判断是否开启 AOF 持久化,开启继续执行后续流程,未开启执行加载 RDB 文件的流程。
  2. 判断 appendonly.aof 文件是否存在,文件存在则执行后续流程。
  3. 判断 AOF 文件开头是 RDB 的格式, 先加载 RDB 内容再加载剩余的 AOF 内容。
  4. 判断 AOF 文件开头不是 RDB 的格式,直接以 AOF 格式加载整个文件。
image-20240417212632723