Redis 持久化方式-AOF

2020-12-13 13:13:11 浏览数 (1)

首先如果对RDB不太熟悉的朋友可以阅读Redis 持久化方式-RDB 加以理解。

本篇主要梳理AOF持久化方式 AOF的工作原理是以独立日志的方式记录每次写命令, 重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。

AOF 的主要作用是解决了数据持久化的实时性, 目前已经是 Redis 持久化的主流方式。

使用AOF

归纳步骤

  • 开启 AOF: appendonly yes, 默认不开启
  • 文件名: appendfilename 配置, 默认 appendonly.aof
  • 保存路径: 配置方法和 RDB 一样

流程说明

说明:rewrite 用于压缩

命令写入

文本协议格式:

代码语言:javascript复制
*3rn$3rnsetrn$5rnhellorn$5rnworldrn

为什么采用文本协议?

  • 文本协议具有很好的兼容性
  • 开启 AOF 后, 所有写入命令都包含追加操作, 直接采用 (文本?) 协议格式, 避免了二次处理开销 (编解码?)
  • 文本协议具有可读性, 方便直接修改和处理

为什么把命令追加到 aof_buf 中?

  • 避免性能完全取决于磁盘
  • 提供多种缓冲区同步硬盘策略, 在性能和安全性方面做出平衡

文件同步

同步策略由 appendfsync 控制:

  • write 操作会触发延迟写 (delayed write) 机制。Linux 在内核提供页缓冲区用来提高硬盘IO性能。write 操作在写入系统缓冲区后直接返回。同步硬盘操作依赖于系统调度机制, 例如: 缓冲区页空间写满或达到特定时间周期。同步文件之前, 如果此时系统故障宕机, 缓冲区内数据将丢失。
  • fsync 针对单个文件操作 (比如 AOF 文件), 做强制硬盘同步, fsync 将阻塞直到写入硬盘完成后返回, 保证了数据持久化。
  • 配置为 always 时, 每次写入都要同步 AOF 文件, 在一般的 SATA 硬盘上, Redis 只能支持大约几百 TPS 写入, 显然跟 Redis 高性能特性背道而驰, 不建议配置。
  • 配置为 no, 由于操作系统每次同步 AOF 文件的周期不可控, 而且会加大每次同步硬盘的数据量, 虽然提升了性能, 但数据安全性无法保证。
  • 配置为 everysec, 是建议的同步策略, 也是默认配置, 做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据。(严格来说最多丢失1秒数据是不准确的, 5.3节会做具体介绍到。)

重写机制

压缩文件体积

AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程.

重写后的AOF文件为什么可以变小?

  • 进程内已经超时的数据不再写入文件
  • 旧的 AOF 文件含有无效命令, 如 del key1、hdel key2、srem keys、set a111、set a222 等。重写使用进程内数据直接生成, 这样新的AOF文件只保留最终数据的写入命令
  • 多条写命令可以合并为一个, 如: lpush list a、lpush list b、lpush list c可以转化为: lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢出, 对于 list、set、hash、zset 等类型操作, 以64个元素为界拆分为多条

更小的 AOF 文件可以更快地被 Redis 加载

AOF重写过程可以手动触发和自动触发:

  • 手动触发: 直接调用 bgrewriteaof 命令
  • 自动触发: 根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机
    • auto-aof-rewrite-min-size: 表示运行 AOF 重写时文件最小体积, 默认为 64MB
    • auto-aof-rewrite-percentage: 代表当前 AOF 文件空间 (aof_current_size) 和上一次重写后 AOF 文件空间 (aof_base_size) 的比值
    • 自动触发时机 = aof_current_size > auto-aof-rewrite-min-size && (aof_current_size-aof_base_size)/aof_base_size >= auto-aof-rewrite-percentage
    • aof_rewrite_buf: 保存 fork 过程中新接收的命令
    • 每次批量写入硬盘数据量由配置 aof-rewrite-incremental-fsync 控制, 默认为 32MB, 防止单次刷盘数据过多造成硬盘阻塞

重启加载

文件校验

加载损坏的 AOF 文件时会拒绝启动

对于错误格式的 AOF 文件, 先进行备份, 然后采用 redis-check-aof--fix 命令进行修复, 修复后使用 diff -u 对比数据的差异, 找出丢失的数据,有些可以人工修改补全

AOF 文件可能存在结尾不完整的情况, 比如机器突然掉电导致 AOF 尾部文件命令写入不全。Redis 为我们提供了 aof-load-truncated 配置来兼容这种情况,默认开启。加载 AOF 时, 当遇到此问题时会忽略并继续启动, 同时打印如下警告日志:

0 人点赞