Redis持久化之AOF的定义及执行原理

Redis 提供了 RDB 和 AOF 两种持久化机制,前者将当前的数据保存到磁盘,后者则是将每次执行的写命令保存到磁盘(类似于 MySQL 的 Binlog)。本文将详细介绍 AOF 持久化方案,包括操作方法和持久化的实现原理
RDB持久化方案,请参考Redis持久化之RDB

一、定义

以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,
redis启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

二、执行流程

  1. 客户端的请求写命令会被append追加到AOF缓冲区内;
  2. AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
  3. AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
  4. Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

三、三种执行策略

always:

每次有新命令追加到 AOF 文件时就执行一次 fsync ——速度非常慢,但是很安全

everysec:

每秒同步,每秒记入日志一次。——推荐且默认模式,如果宕机,本秒的数据可能丢失,保障速度的同时也可以在一定程度上保证数据安全

no:

redis不主动进行同步,把同步时机交给操作系统(系统的写缓存被刷新时执行)。

四、AOF配置文件

AOF默认是不开启的

#配置开始AOF开启
appendonly yes 

#配置AOF文件名称,其存放路径和RDB一致
appendfilename "appendonly.aof" 

#配置AOF执行策略
appendfsync everysec 

#数据持久化文件存储目录
dir /var/lib/redis

# 是否在执行重写时不同步数据到AOF文件
# 这里的 yes,就是执行重写时不同步数据到AOF文件
no-appendfsync-on-rewrite yes

# 触发AOF文件执行重写的最小尺寸
auto-aof-rewrite-min-size 64mb

# 触发AOF文件执行重写的增长率
auto-aof-rewrite-percentage 100

Redis持久化之AOF的定义及执行原理

五、AOF重写

1)定义

AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制, 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof

2)作用

① 减少磁盘占用量
② 加速数据恢复

3)重写的触发

方式一: bgrewrite命令

AOF 重写由 Redis 自行触发,bgrewriteaof 仅仅用于手动触发重写操作。

方式二: 配置文件配置自动触发

AOF重写自动触发机制,需要同时满足下面两个条件:auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage
如上述配置表示:当AOF文件的体积大于64Mb,并且AOF文件的体积比上一次重写之久的体积大了至少一倍(100%)时,Redis将执行 bgrewriteaof 命令进行重写。

4)重写的执行逻辑

(1)bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
(2)主进程fork出子进程执行重写操作,保证主进程不会阻塞。
(3)子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
(4)1).子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。2).主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
(5)使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。
Redis持久化之AOF的定义及执行原理

六、AOF的优缺点

优点:

备份机制更稳健,丢失数据概率更低。
AOF文件是一个只进行追加的日志文件,所以不需要写入seek,可通过redis-check-aof工具修复
AOF文件具有可读性,可以很轻松的分析文件,也可以处理误操作。

缺点:
  • 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
  • 恢复备份速度要慢。
  • 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。每次读写都同步的话,有一定的性能压力。
上一篇:PostgreSQL 空间类型统计信息(Statistics, Cardinality, Selectivity, Estimate)不准确导致SQL执行计划不准(包含、相交查询)的优化实践


下一篇:C# 浅拷贝与深拷贝区别