AOF (Append Only File)

在每个 “写” 命令被 redis 执行后,将该命令记录到 AOF 日志中。

为什么是在 “写” 命令执行后记录?

因为记录 AOF 时不会检查命令是否正确,而在命令执行后记录,可确保命令能被正确执行且不会阻塞主线程的 “写” 操作。

何时落盘?

  • Always:命令执行完毕后,立即将 AOF 日志落盘
  • Eveerysec:每秒将 AOF 日志落盘一次
  • No:由操作系统决定 AOF 日志何时落盘

    重写

    当 AOF 日志文过大时,会触发 AOF 重写
  1. 主线程 fork 出一个后台子线程 bgrewriteaof
    1. 主线程会将子线程需要的数据结构拷贝一份,其中包括内存页表(虚拟内存和物理内存的映射索引表)
    2. 当前操作会阻塞主线程
  2. 子线程使用最新数据生成 “写” 命令并写入新的 AOF日志中
  3. 重写过程中,主线程写入新的数据时,在命令执行后将命令同时写入主线程的 AOF 日志以及子线程的 AOF 重写日志中
  4. 重写过程中,主线程修改旧数据时使用 “写时拷贝” 机制,即将需要修改的数据拷贝一个备份出来,主线程将新数据写入备份不会影响 AOF 的重写
  5. 步骤 2 执行完毕后,子线程会将 AOF 重写日志中的内容追加到新的 AOF 日志中
  6. 将子线程重写后的 AOF 日志替换主线程的 AOF 日志

image.pngimage.png

RDB (Redis DataBase)

RDB 是一种以二进制文件存储的数据快照。

save

在主线程中生成 RDB,会造成主线程的阻塞

bgsave

会创建一个专门用于写入 RDB 的子线程

  • fork 子线程时,会阻塞主线程
  • 使用 “写时拷贝” 机制,避免数据不一致
  • Redis 的默认方式

    增量快照

    所谓 “增量快照” 是指第一次快照全库数据,从第二次开始每次只快照那些在第一次快照后新增、修改的数据。

    RDB + AOF

    Redis version >= 4.0

以一定频率执行快照,使用 AOF 记录每次快照间的操作,并在每次快照后清空 AOF 日志。

主从间如何保证数据的一致性?

前提:

  1. run_id:Redis 实例的唯一 id
  2. offset:偏移量
  3. 主库会持有一个环境列表,使用 offset 标识当前最新数据的位置

新增从库时

  1. 从库向主库发起请求、协商同步(run_id=? & offset=-1)
  2. 主库使用 FULLRESYNC 相应请求并返回 run_id & offset
  3. 主库返回当前最新数据的全量 RDB 文件
  4. 从库清空现有数据后,加载 RDB
  5. 主库返回生成 RDB 期间所执行的 “写命令”
  6. 主从保持长链接

image.png

从库宕机恢复

  1. 从库连接恢复后,从库发送同步请求(run_id & offset)
  2. 主库发送 >从库 offset 且 <主库 offset 的增量数据
  3. 主从保持长链接

image.png