Redis--持久化之AOF

AOF持久化

AOF Append only FIle,指Redis将每一次的写操作以日志形式记录到一个AOF文件中的持久化技术。

需要恢复内存数据时,将这些写操作重新执行一次,就会恢复到之前的内存数据状态。

AOF基础配置

AOF的开启

sh 复制代码
# 在Redis配置文件中配置如下:
appendonly yes

默认情况下此配置关闭。

文件名配置

sh 复制代码
appendfilename "appendonly.aof"

Redis7 在这里发生了重大变化,原来只有一个appendonly.aof文件,现在具有了三类多个文件:

  • 基本文件:可以是RDB格式也可以是AOF格式,其存放内容是由RDB转换为AOF当时内存的快照数据。该文件可以有多个。
  • 增量文件:以操作日志形式记录转为AOF后的写入操作,该文件可以有多个。
  • 清单文件:用于维护AOF文件的创建顺序,保证激活时的应用顺序。该文件只有一个。

混合持久化开启

sh 复制代码
aof-use-rdb-preamble yes

对于基本文件可以是RDB格式也可以是AOF格式,通过aof-use-rdb-preamble属性可以设置。默认yes。

默认AOF持久化的基本文件以rdb格式,也就是默认启用混合持久化。

AOF文件目录配置

sh 复制代码
appenddirname "appendonlydir"

AOF持久化文件指定存放目录,默认为Redis安装目录。

AOF文件格式

AOF文件包含三类文件:基本文件、增量文件和清单文件。

基本文件一般是rdb格式,下面将解释增量文件和清单文件的内容格式。

Redis协议

增量文件扩展名为.aof,AOF格式就是Redis通讯协议格式,AOF文件的本质就是基于Redis通讯协议的文本,将命令以纯文本的方式写入到文件中。

Redis协议规定,Redis文本以行来划分,每行以\r\n结束,每一行都有一个消息头,表示消息类型,消息头有6种不同符号表示:

  • (+):表示一个正确的状态信息
  • (-):表示一个错误信息
  • (*):表示消息体总共有多少行,不包括当前行
  • ($):表示下一行消息数据的长度,不包括换行符长度\r\n
  • (空):表示一个消息数据
  • (:):表示返回一个数值

查看AOF文件

打开appendonly.aof.1.incr.aof 文件,可以看到如下格式内容:

以上内容有三条命令:一条数据库切换命令select 0,两条set命令。其意义如下:

sh 复制代码
*2   # 表示当前命令包含2个参数
$6  # 表示第一个参数包含6个字符
select # 第一个参数
$1 # 表示第二个参数包含1个字符
0 # 第二个参数
*3 #表示当前命令包含3个参数
$3 # 表示第一个参数包含3个字符
set # 第一个参数
$3 #表示第二个参数包含3个字符
k11 #表示第二个参数
$3 #表示第三个参数包含3个字符
v11 #表示第三个参数

清单文件

打开清单文件appendonly.aof.manifest,查看其内容如下:

该文件会先安装seq序号列出所有基本文件,基本文件type类型为b,

再安装seq序号列出所有增量文件,增量文件type类型为i。

当Redis启动数据恢复,会按照该文件由上到下依次加载他们中的数据。

Rewrite机制

随着时间推移,AOF文件会越来越大,为了放置AOF文件过大占用大量的空间,降低性能,Redis引入了Rewrite机制对AOF文件进行压缩。

什么是Rewrite

Rewrite就是对AOF文件进行重写整理

当Rewrite开启后,主进程redis-server创建一个子进程bgrewriteaof,该子进程完成Rewrite过程。

其首先对现有aof文件进行Rewrite计算,将计算结果写入到一个临时文件,写入完毕后,再rename该临时文件为aof文件,覆盖原有文件。

Rewrite计算

Rewrite计算也称Rewrite策略。Rewrite计算遵循以下策略:

  • 读操作不写入文件
  • 无效命令不写入文件(对同一个key多次写命令,只写入最新的指令)
  • 过期数据不写入文件
  • 多条命令合并写入文件

手动开启Rewrite

Rewrite开启有两种方式:bgrewriteaof命令手动开启;设置条件自动开启。

bgrewriteaof命令会使主进程redis-server创建出一个子进程bgrewriteaof,有此子进程完成rewrite过程。

在Rewrite期间,redis-server仍可以对外提供读写服务。

自动开启Rewrite

通过设置一些条件,当条件满足后才会开启。可在配置文件中对Rewrite自动启动条件设置:

  • auto-aof-rewrite-percentage:开启rewrite的增大比例,默认100%。指定为0.表示禁用自动rewrite。
  • auto-aof-rewrite-min-size:开启rewrite的AOF文件最小值,默认64M。该值的设置主要是为了放置小AOF文件被rewrite,从而导致性能下降。

当AOF日志文件大小增长到指定的百分比时,主进程redis-server创建出一个子进程bgrewriteaof来完成rewrite过程。

其工作原理如下:

复制代码
Redis会记住最新rewrite后的AOF文件大小作为基本大小,
如果从主机启动后就没有发生过重写,基本大小就是启动时AOF的大小。
如果当前AOF文件大于基本大小的指定百分比阈值,且当前AOF文件大于配置文件中指定的最小阈值,则会触发rewrite。

AOF优化配置

appendfsync

当客户端提交写操作命令后,该命令就会写入到aof_buf中,而aof_buf中的数据持久化到AOF文件的过程称为数据同步。

何时将aof_buf的数据同步到AOF文件?

采用不同的数据同步策略,同时的时机是不同的,有三种策略:

  • always:写操作命令写入到aof_buf后立即调用fsync()函数,将其追加到AOF文件 。该策略效率低,比较安全,不会丢失太多数据。 最多就是丢失刚刚执行的写操作。
  • no:写操作命令写入到aof_buf后什么也不做,不会调用fsync()函数。由操作系统负责将aof_buf中的数据同步到磁盘 ,Linux系统默认同步周期是30秒,效率较高
  • everysec:默认策略 。写操作命令写入aof_buf后不直接调用fsync(),而是每秒调用一次fsync() 来完成同步。该策略兼顾性能与安全,是一种折中方案。

no-appendfsync-on-rewrite

该属性指定,当AOF fsync策略设置为always或everysec,当主进程创建子进程正在执行bgsave或bgrewriteaof时,主进程是否不调用fsync()来做数据同步

设置为no,双重否定即肯定,主进程会调用fsync()做同步;

设置为yes,则不会调用fsync()做数据同步。

如果调用fsync(),在同步数据量非常大时,会阻塞主进程对外提供服务;

如果不调用fsync(),可能会存在30秒数据丢失风险。

aof-rewrite-incremental-fsync

当bgrewriteaof在执行时,先将rewrite计算结果写入到aof_rewrite_buf缓存中,当缓存数据达到一定量后就会调用fsync()进行刷盘操作,即数据同步。

该属性用户控制fsync()每次刷盘的数据量最大不超过4MB。这样可以避免由于单次刷盘量过大而引发长时间阻塞。

aof-load-truncated

在进行AOF持久化时,系统突然宕机,此时写入到AOF文件中的最后一条数据可能不完整,当主机启动后,Redis在AOF文件不完整的情况下是否可以启动,由aof-load-truncated设置。其值为:

  • yes:AOF文件最后不完整的数据会被截断删除,不影响Redis启动。
  • no:不删除不完整数据,Redis无法启动.

aof-timestamp-enabled

该属性设置为yes,会在AOF文件中显示时间戳,方便按照时间对数据进行恢复.

但是,该方式可能会与AOF解析器不兼容,所以默认为no,不开启.

AOF持久化过程

AOF持久化过程如下:

  1. Redis接收到写命令后将命令按照Redis通讯协议格式暂时添加到AOF缓冲区aof_buf。
  2. 根据数据同步策略,再将缓冲区的数据一次性写入磁盘的AOF文件,以减少io次数,提高性能。
  3. 当AOF文件达到rewrite条件时,redis-server主进程会fork一个子进程bgrewriteaof,由该子进程完成rewrite过程。
  4. 子进程先对AOF文件进行rewrite计算,将计算结果写入一个临时文件,全部写入完毕后,再rename该临时文件,覆盖原文件。
  5. 如果在rewrite过程种又有写命令追加,那么这些数据会写入aof_rewrite_buf缓冲区。等将rewrite计算结果写入临时文件后,会先将aof_rewrite_buf缓冲区的数据写入到临时文件,然后再rename成源文件名称,覆盖原文件。

RDB与AOF对比

优点 缺点
RDB 文件小、恢复快 安全性差、写时复制会降低性能、RDB文件可读性差
AOF 安全性高、AOF文件可读性强 文件大、写操作影响性能、数据恢复慢

官方推荐使用RDB与AOF混合式持久化

如果数据安全性要求不高,推荐使用RDB方式

不推荐使用纯AOF方式

若Redis仅用作缓存,则无需使用任何持久化技术。

相关推荐
budingxiaomoli2 小时前
注册中心的其他实现-Nacos
java·spring cloud·微服务
大大大大晴天️3 小时前
Flink技术实践-Flink重启策略选型指南
java·大数据·flink
ffqws_3 小时前
Spring @Transactional 注解详解:从入门到避坑
java·数据库·后端·spring
xuhaoyu_cpp_java3 小时前
单调栈(算法)
java·数据结构·经验分享·笔记·学习·算法
黑夜里的小夜莺3 小时前
黑马点评登录成功后点击【我的】会跳转到登录页面 BUG 修复
java·bug
wuyikeer3 小时前
Java进阶——IO 流
java·开发语言·python
fengxin_rou4 小时前
JVM 内存结构与内存溢出 / 泄漏问题全解析
java·开发语言·jvm·分布式·rabbitmq
城俊BLOG4 小时前
C++的注册机制和插件系统
java·服务器·c++
Try,多训练4 小时前
软件设计师备考第一性原理分析
java·经验分享·学习方法