Redis 源码简洁剖析 15 - AOF

2023-02-22,,

AOF 是什么
AOF 持久化的实现
命令追加
AOF 文件的写入和同步
AOF 文件的载入和数据还原
AOF 重写
为什么需要重写
什么是重写
如何重写
AOF 后台重写
为什么需要后台重写
带来的问题
AOF 重写缓冲区
注意
实际例子
参考链接
Redis 源码简洁剖析系列

AOF 是什么

Append Only File,通过保存 Redis 服务器所执行的命令来记录数据库状态。

AOF 持久化的实现

命令追加

服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾:

struct redisServer {
……
// AOF 缓冲区
sds aof_buf;
……
}

AOF 文件的写入和同步

AOF 文件的载入和数据还原

流程:

AOF 重写

为什么需要重写

AOF 持久化是通过保存被执行的写命令来记录数据库状态的,随着服务器运行时间的流逝,AOF 文件的内容会越来越多,文件体积越来越大。如果客户端执行了下面的命令:

127.0.0.1:6379> set name yano
OK
127.0.0.1:6379> set name yano2
OK
127.0.0.1:6379> set name yano3
OK

那么 AOF 文件就需要保存 3 条命令,不仅使保存的 AOF 文件体积变大,还使得 Redis 启动时载入数据变慢。

什么是重写

AOF 文件重写(rewrite),创建新的 AOF 文件替代现有的 AOF 文件,新旧两个 AOF 文件所保存的数据库状态相同,但新 AOF 文件不会包含任何浪费空间的冗余命令,体积更小。

如何重写

不是读取和分析现有的 AOF 文件内容,而是直接从数据库读取值组成相应的命令 AOF 文件。

AOF 后台重写

为什么需要后台重写

重写函数 aof_rewrite 会进行大量的写入操作,执行这个函数的线程会被长时间阻塞,但是 Redis 服务器使用单个线程来处理命令请求,如果直接在主线程直接更新,在重写期间,服务器将无法处理客户端发来的命令请求。所以将 AOF 重写程序放到子进程中执行。

带来的问题

子进程在进行 AOF 重写期间,服务器进程还需要继续处理命令请求,新的命令可能对现有的数据库状态进行修改,导致服务器当前数据库状态和重写后的 AOF 文件保存的数据状态不一致。

AOF 重写缓冲区

为了解决这种数据不一致的问题,Redis 设置了一个 AOF 重写缓冲区,在服务器创建子进程之后开始使用,当 Redis 服务器执行完一个写命令后,同时将这个写命令发送给 AOF 缓冲区AOF 重写缓冲区

当子进程完成 AOF 重写工作后,它会向父进程发送一个信号,父进程在收到这个信号后,会调用一个信号处理函数:

    将 AOF 重写缓冲区的所有内容写入新的 AOF 文件,这样新 AOF 文件所保存的数据库状态就与服务器当前的数据库状态一致;
    对新 AOF 文件改名,原子覆盖现有的 AOF 文件,完成新旧 AOF 文件的替换。

下图左边是正常流程,右边是 AOF 重写期间的流程:

注意

在实际中,为了避免在执行命令时造成客户端输入缓冲区的溢出,重写程序在处理列表、哈希表、集合、有序集合可能带有多个元素的键时,会先检查键所包含的元素数量,如果元素数量超过了一个常量阈值,重写程序会使用多条命令来记录键的值。

实际例子

配置 redis.conf 文件,使用 AOF:

appendonly yes
appendfsync always
appendfilename "appendonly.aof"
dir ./

启动 Redis server:

src/redis-server redis.conf&

启动 Redis client:

src/redis-cli

设置 key:

127.0.0.1:6379> set name yano
OK
127.0.0.1:6379> set name yano2
OK
127.0.0.1:6379> set name yano3
OK

查看 appendonly.aof 文件:

➜  redis-6.2.6 cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$4
yano
*3
$3
set
$4
name
$5
yano2
*3
$3
set
$4
name
$5
yano3

参考链接

19 | AOF 重写(上):触发时机与重写的影响
《Redis 设计与实现》- 第 11 章 AOF 持久化
Redis Persistence

Redis 源码简洁剖析系列

最简洁的 Redis 源码剖析系列文章

Java 编程思想-最全思维导图-GitHub 下载链接,需要的小伙伴可以自取~

原创不易,希望大家转载时请先联系我,并标注原文链接。

Redis 源码简洁剖析 15 - AOF的相关教程结束。

《Redis 源码简洁剖析 15 - AOF.doc》

下载本文的Word格式文档,以方便收藏与打印。