# 持久化

# AOF日志系统

AOF 日志是后写日志,Redis 先执行命令,将数据写入内存后才记录日志。

# 写回策略

对于 AOF 的写回策略,其配置项 appendfsync 中给出了三种可选项:

  • Always
    • 同步写回。每个写命令执行完之后立刻同步地将日志写回磁盘。
    • 优点:可靠性高,数据基本不会丢失
    • 缺点:性能影响较大
  • Everysec
    • 每秒写回。每个写命令执行完毕后,只把日志写入到 AOF 内存缓冲区,之后每隔一秒把缓冲区的内容写入磁盘。
    • 优点:性能适中
    • 缺点:宕机时丢失一秒内的数据
  • No
    • 操作系统控制写回。每隔写命令执行完毕后,只把日志写入到 AOF 内存缓冲区,之后由操作系统决定何时将缓存写回到磁盘。
    • 性能好
    • 宕机时丢失数据较多

具体根据对系统的高性能和高可靠性要求来选择写回策略。

# 重写机制

当随着系统运行,命令增多时,AOF 文件也会逐渐变大。Redis 会在重写时根据数据库的状况新建一个 AOF 文件,称为重写机制。即读取数据库内所有键值对,然后对每一条记录用一个命令记录下来。以这样的方法可以合并旧日志文件中某些命令,在重写时只保存一条。

重写过程为一个拷贝,两处日志。它不由主线程写回,而是由后台线程 bgrewriteaof 完成。
当发生重写时,主线程将主线程内存拷贝一份给 bgrewriteaof 子线程中,之后子线程逐一将数据写成操作记入重写日志。
第一处日志指当前正在运行的 AOF 日志。在重写过程中,主线程不会阻塞,这时仍然可能会有新的操作进行。Redis 会将操作继续写入旧 AOF 日志中。
第二处日志是重写的新 AOF 日志。通过两处日志,在重写完成后继续将旧 AOF 中的新操作写入新 AOF 中来保证数据库最新状态,之后用新 AOF 代替旧 AOF.

# RDB快照系统

Redis Database (RDB) 记录某一时刻的数据,它记录内存中的所有数据。
RDB 文件生成使用命令 savebgsave 两种。其中 save 在主线程中执行,会阻塞主线程;而 bgsave` 创建一个子进程专门写入 RDB 文件,是默认配置。
为了避免创建 RDB 文件时不可以正常处理写操作的问题,Redis 采用了 Copy on write 技术。快照子线程共享主线程的内存数据。当主线程为读操作时不受影响。当主线程对数据修改时,被修改数据会复制一份,子线程将副本数据写入 RDB 文件。

# AOF 与 RDB 联合使用

为了避免连续快照或者增量快照带来的高消耗,Redis 采用了混合使用 AOF 和 RDB 的方法来保证数据持久化的正确性。即内存快照以一定频率执行,每两次之间使用 AOF 记录所有操作。
通过这样的方法,避免了 RDB 快照频繁对主线程的影响,也避免了 AOF 重写过大的开销。

启发规则:

  • 当要保证数据不丢失时,联用 RDB 和 AOF
  • 允许分钟级别的数据丢失时,可只启用 RDB
  • 若只能使用 AOF,则优先选择 everysec 配置