Redis 持久化机制 AOF

文若3年前技术文章899


前言

Redis 有两种持久化机制,分别是 RDB 与 AOF 本篇文章将介绍 AOF 的执行过程与应用。

1. AOF 简介

AOF (Append only file) 持久化是以独立日志的方式记录每次写命令,重启时再重新读取文件中的命令,以达到恢复数据的目的。AOF 主要是为了解决数据持久化的实时性。

3. 参数设置

2.1 开启 AOF

开启 AOF 功能需要设置参数:appendonly yes 下方是查询参数语句:

127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"

2.2 保存路径

默认文件名为:appendonly.aof 保存的路径与 RDB 配置一致,通过 dir 参数配置:

27.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/redis-5.0.0"

2.3 文件同步

Redis 提供三种 AOF 缓冲区同步策略,由 appendfsync 参数控制,具体含义将在 3.2 文件同步策略介绍。

127.0.0.1:6379> config get appendfsync
1) "appendfsync"
2) "everysec"

2.4 日志重写

AOF 日志文件过大,可触发重写机制,达到收缩日志目的,具体含义将在 3.3 日志重写机制介绍。

127.0.0.1:6379> config get auto-aof-*
1) "auto-aof-rewrite-percentage"
2) "100"
3) "auto-aof-rewrite-min-size"
4) "67108864"

3. AOF 实现解析

3.1 写入流程

我们熟悉的日志同步机制,例如 WAL 日志优先写,在实际写数据前,先修改的数据记录到文件中,便于故障恢复。Redis AOF 机制正好相反,它属于 “写后” 日志,先将命令执行把数据写入内存,再将命令写入日志。

这样做有两个优势:

1)避免语法检测带来的开销,命令先执行成功才会写入日志。

2)命令执行后才写入日志,不会堵塞当前写入操作。

AOF 命令写入使用的是文本协议格式,具有较好的兼容性,避免二进制处理开销,具有可读性,方便直接修改和处理。写入流程可见下图:

截屏2022-12-21 下午3.32.09.png

1)所有的写入命令会被追加到 Aof buffer 缓冲区中。

2)AOF 缓冲区根据对应的策略将数据同步到磁盘。

3)随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩对目的。

4)当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

3.2 文件同步策略

Redis 提供三种 AOF 日志写回磁盘策略,由参数 appendfsync 控制,下面对参数有效值逐一介绍:

always 同步写回

命令写入 Aof buffer 后调用系统 fsync 操作同步到 AOF 文件中,fsync 完成后线程可返回。

always 可以做到基本不丢数据,但是在命令执行完后,都会有一个慢速的 fsync 操作,不可避免会影响主线程性能。

优点:可靠性高   缺点:对性能影响较大

everysec 每秒写回

命令写入 Aof buffer 后调用系统 write 操作,write 完成后线程返回。fsync 同步文件操作由专门线程每秒调用一次。

每隔一秒进行一次 AOF 日志刷盘操作,一旦宕机会丢失一秒的数据。是 Redis 默认同步策略。

优点:性能适中  缺点:可能会丢失 1 秒数据  默认选项

no 操作系统控制写回

命令写入 Aof buffer 后调用系统 write 操作,不对 AOF 文件做 fsync 同步,同步磁盘的操作由操作系统负责

通常同步周期最长 30 秒。

每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。

优点:性能高    缺点:宕机会丢失较多数据

3.3 日志重写机制

随着命令不断写入 AOF,文件会越来越大,为了解决这个问题,Redis 引入 AOF 重写机制压缩文件体积。AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程。

重写后为什么文件会变小?

1)进程内已超时的数据不再写入文件。

2)旧的 AOF 文件含有无效命令,如 delkey1、hdelkey2、sremkeys、seta111、seta222 等。重写使用进程内数据直接生成,这样新的 AOF 文件只保留最终数据的写入命令。

3)多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c 可以转化为:lpush list a b c。

AOF 重写机制降低文件占用空间,更小的 AOF 文件也会被更快的加载。

手动触发

执行下方 bgrewriteaof 命令:

bgrewriteaof

自动触发

根据下方两个参数确定自动触发的时机。

  • auto-aof-rewrite-min-size:表示运行 AOF 重写时文件的最小大小,默认为 64MB。

  • auto-aof-rewrite-percentage:当前 AOF 文件大小和上一次重写后 AOF 文件大小的差值,再除以上一次重写后 AOF 文件大小。也就是当前 AOF 文件比上一次重写后 AOF 文件的增量大小,和上一次重写后 AOF文件大小的比值。

3.4 日志重写过程

执行日志重写期间,不会影响主线程正常响应命令。如何实现的呢?

主线程 fork 出后台的 bgrewriteaof 子进程。fork 会把主线程的内存拷贝一份给 bgrewriteaof 子进程,这里面就包含了数据库的最新数据。然后,bgrewriteaof 子进程就可以在不影响主线程的情况下,逐一把拷贝的数据写成操作,记入重写日志。

因为主线程未阻塞,仍然可以处理新来的操作。此时,如果有写操作,会写入原来的 AOF Buffer 保障此时宕机也可以恢复。当然该操作也会被写入重写日志缓冲区,这样重写日志也不会丢失最新的数据。


相关文章

GET和POST请求的区别

GET和POST请求的区别GET请求GET /books/?sex=man&name=Professional HTTP/1.1 Host: www.wrox.com User-Agent...

PromQL查询解析

一. 概述Prometheus除了存储数据外,还提供了一种强大的功能表达式语言 PromQL,允许用户实时选择和汇聚时间序列数据。表达式的结果可以在浏览器中显示为图形,也可以显示为表格数据,或者由外部...

xtrabackup全量备份恢复操作

xtrabackup全量备份恢复操作

一、核实环境1、核实服务器环境cat /etc/centos-release2、核实数据库版本随着Percona XtraBackup 8.0 的推出,Percona XtraBackup 2.4将继...

MySQL优化器特性(一)IN和Exists(semijoin)子查询优化策略

这篇文章中的SQL和执行计划在mysql 8.0.31环境下进行测试。测试的表结构和数据:表结构mysql> show create table tp\G...

RabbitMQ 集群部署

RabbitMQ 集群部署

1. 两种模式说到集群,小伙伴们可能第一个问题是,如果我有一个 RabbitMQ 集群,那么是不是我的消息集群中的每一个实例都保存一份呢?这其实就涉及到 RabbitMQ 集群的两种模式:1)普通集群...

MySQL 8.0 新特性:Instant Add Column

MySQL 8.0 新特性:Instant Add Column

一、前言MySQL 8.0 支持 “快速加列” 功能,既添加字段时可以支持 “INSTANT” 快速完成。通过只修改数据字典的方法来实现大表快速加列,避免之前加列操作必须做的数据拷贝,从而大幅缩小大表...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。