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 重写工作后,它会向父进程发送一个信号,父进程在收到这个信号后,会调用一个信号处理函数:

  1. 将 AOF 重写缓冲区的所有内容写入新的 AOF 文件,这样新 AOF 文件所保存的数据库状态就与服务器当前的数据库状态一致;
  2. 对新 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

参考链接

Redis 源码简洁剖析系列

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

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

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

Redis 源码简洁剖析 15 - AOF的更多相关文章

  1. Redis 源码简洁剖析 03 - Dict Hash 基础

    Redis Hash 源码 Redis Hash 数据结构 Redis rehash 原理 为什么要 rehash? Redis dict 数据结构 Redis rehash 过程 什么时候触发 re ...

  2. Redis 源码简洁剖析 07 - main 函数启动

    前言 问题 阶段 1:基本初始化 阶段 2:检查哨兵模式,执行 RDB 或 AOF 检测 阶段 3:运行参数解析 阶段 4:初始化 server 资源管理 初始化数据库 创建事件驱动框架 阶段 5:执 ...

  3. Redis 源码简洁剖析 11 - 主 IO 线程及 Redis 6.0 多 IO 线程

    Redis 到底是不是单线程的程序? 多 IO 线程的初始化 IO 线程运行函数 IOThreadMain 如何推迟客户端「读」操作? 如何推迟客户端「写」操作? 如何把待「读」客户端分配给 IO 线 ...

  4. Redis 源码简洁剖析 13 - RDB 文件

    RDB 是什么 RDB 文件格式 Header Body DB Selector AUX Fields Key-Value Footer 编码算法说明 Length 编码 String 编码 Scor ...

  5. Redis 源码简洁剖析 16 - 客户端

    整体概述 客户端属性 套接字描述符 标志 输入缓冲区 命名及命令参数 命令的实现函数 输出缓冲区 客户端的创建与关闭 创建普通客户端 关闭普通客户端 参考链接 Redis 源码简洁剖析系列 整体概述 ...

  6. Redis 源码简洁剖析 02 - SDS 字符串

    C 语言的字符串函数 C 语言 string 函数,在 C 语言中可以使用 char* 字符数组实现字符串,C 语言标准库 string.h 中也定义了多种字符串操作函数. 字符串使用广泛,需要满足: ...

  7. Redis 源码简洁剖析 04 - Sorted Set 有序集合

    Sorted Set 是什么 Sorted Set 命令及实现方法 Sorted Set 数据结构 跳表(skiplist) 跳表节点的结构定义 跳表的定义 跳表节点查询 层数设置 跳表插入节点 zs ...

  8. Redis 源码简洁剖析 05 - ziplist 压缩列表

    ziplist 是什么 Redis 哪些数据结构使用了 ziplist? ziplist 特点 优点 缺点 ziplist 数据结构 ziplist 节点 pre_entry_length encod ...

  9. Redis 源码简洁剖析 06 - quicklist 和 listpack

    quicklist 为什么要设计 quicklist 特点 数据结构 quicklistCreate quicklistDelIndex quicklistDelEntry quicklistInse ...

随机推荐

  1. Enumy:一款功能强大的Linux后渗透提权枚举工具

    Enumy是一款功能强大的Linux后渗透提权枚举工具,该工具是一个速度非常快的可移植可执行文件,广大研究人员可以在针对Linux设备的渗透测试以及CTF的后渗透阶段利用该工具实现权限提升,而Enum ...

  2. YC-Framework版本更新:V1.0.5

    分布式微服务框架:YC-Framework版本更新V1.0.5!!! 本次版本V1.0.5更新 所有模块依赖调整: 部分问题修复: Nacos模块化: Eureka模块化: 支持SOA(即WebSer ...

  3. 校招——面试(Android岗)总结

    PS:持续更新,未完待续 2016.8.24某为面试 自我介绍一下 链表和数组的区别 数组的存储空间是静态.连续分布的,初始化过大会造成空间浪费,过小会使空间溢出:链表的存储空间是动态分布的,只要内存 ...

  4. 【linux】Ubuntu20.04使用apt下载和卸载openJDK

    Ubuntu20.04使用apt下载和卸载openJDK 前言 由于最近电脑装了ubuntu和win双系统,想再ubuntu上学习.在成功配置完系统之后,开始了配学习环境的旅程.... 这次的是使用u ...

  5. Cesium源码剖析---Ambient Occlusion(环境光遮蔽)

    Ambient Occlusion简称AO,中文没有太确定的叫法,一般译作环境光遮蔽.百度百科上对AO的解释是这样的:AO是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光 ...

  6. Windows Server 2008 R2 数据离机备份与恢复操作手册

    Windows Server 2008 R2 数据离机备份与恢复操作手册 实验环境 Windows server 2008 R2(服务器) IP地址:192.168.136.175 计算机名:CXH ...

  7. 解决for循环中空格的问题

    [root@node-01 ~]# cat 1 a b c ab cd 如果想按行循环遍历出文件中内容,直接使用for是有问题的,第一行按空格分隔的会有问题 [root@node-01 ~]# for ...

  8. Linux中date命令用法

    1.以下是服务器现在的时间,当前时间的各种表示方法,表示成自己想要的时间格式,后面的范例将会在这个时间基础之上进行演示,同时这也是熟练掌握后面各种date命令的前提,请读者注意 [root@RHEL6 ...

  9. Windows 是最安全的操作系统

    建了一个用户交流群,我在群里说:"Windows 是最安全的操作系统." 立刻引发了很多有意思的观点.我在群里一个人说不过大家,先篇文章把自己的论点罗列一下. 对操作系统攻击的方式 ...

  10. [论文][半监督语义分割]Adversarial Learning for Semi-Supervised Semantic Segmentation

    Adversarial Learning for Semi-Supervised Semantic Segmentation 论文原文 摘要 创新点:我们提出了一种使用对抗网络进行半监督语义分割的方法 ...