Redis 持久化机制 AOF

文若1年前技术文章352


前言

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 保障此时宕机也可以恢复。当然该操作也会被写入重写日志缓冲区,这样重写日志也不会丢失最新的数据。


相关文章

PG的多版本并发控制(三)

三、多版本并发控制3.1 常见多版本并发的实现方式第一种方式是,数据库仅保存最新版本数据,将发生变更的旧行版本数据写到其他地方如undo,当需要读取旧版本数据时,通过undo重构。oracle和MyS...

MySQL数据库复制延迟

【问题处理记录】1.查看资源情况,通过查找慢 SQL 发现,从 3:00 开始,存在较多 update 和 delete 操作。怀疑是表结构无主键,由于 RDS 日志模式默认采取的 row 模式,导致...

GET和POST请求的区别

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

Impala 操作命令

Impala 操作命令

Impala的外部shell选项描述-h, --help显示帮助信息-v or --version显示版本信息-i hostname, --impalad=hostname 指定连接运行 impala...

Debezium部署以及同步之DB2数据到Kafka的同步

Debezium部署以及同步之DB2数据到Kafka的同步

因为Debezium依赖于kafka之上,所以我们先部署kafka和zookeeper(忽略)。1 环境介绍Debezium1.9版本 Db2 11.5版本  附官网:http...

spark配置任务日志(Client模式& Cluster模式)

在Spark中,日志级别可以通过log4j.properties或log4j.xml文件来配置。对于spark-submit命令启动的应用程序,可以通过以下两种方式来修改日志级别:对于Client模式...

发表评论    

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