18.Redis系列之AOF方式持久化

news2025/7/19 6:19:35

本文学习redis7两大持久化技术之一:AOF(Append Only File)日志追加方式持久化备份与还原,重写以及AOF方式的优缺点

1. AOF相关配置

首先我们先简单了解下Redis7中AOF相关配置

// 开启AOF方式持久化,默认no
appendonly yes
// AOF持久化名称
appendfilename "appendonly.aof"
// AOF持久化文件存储目录
appenddirname "appendonlydir"
// fsync数据到磁盘策略:默认每秒everysec
appendfsync everysec
// AOF重写时不进行fsync操作,防止redis长时间阻塞
no-appendfsync-on-rewrite no
// AOF重写最小大小为64M,当AOF文件大小扩展一倍时触发重写:如128M, 192M
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
// 当AOF结尾异常,Redis加载时截取正确部分,恢复时不报错,仅仅日志提示
aof-load-truncated yes
// append-only基础文件采用RDB格式 
aof-use-rdb-preamble yes
// AOF记录命令执行时间戳,默认no
aof-timestamp-enabled no

2. AOF备份还原实践

2.1 AOF文件正常情况下还原

修改配置文件为appendonly yes,并启动redis

1

可以看到redis7中,在appendonlydir目录下生成了

  • rdb基础文件
  • incr增量文件
  • manifest管理文件

继续执行以前的测试文件

@SpringBootTest
public class RedisTest {

    @Autowired
    private RedissonClient redissonClient;

    @Test
    public void testRdb() throws InterruptedException {
        RMap<String, String> rMap = redissonClient.getMap("rdb");
        for (int i = 0; i < 10020; i++) {
            rMap.put(i + "", i + "");
        }
        Thread.sleep(60000);
        for (int i = 0; i < 80; i++) {
            rMap.put(i + "ok", i + "ok");
        }
    }
}

操作后我们尝试修改appendonlydir目录名,发现只读不允许修改,我们复制一份重命名为appendonlydirbak模拟备份文件,然后执行

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> shutdown

然后我们删除appendonlydir目录,重命名appendonlydirbak为appendonlydir,然后启动redis, 执行hkeys rdb如图所示,key数量为10100未丢失

2

我们同时配置了RDB与AOF,但redis会已AOF为准进行恢复

2.2 AOF异常状况下进行还原

我们关闭redis服务器,执行命令破坏incr.aof文件

/data # echo 'HELLO WORLD' >> /data/appendonlydir/appendonly.aof.1.incr.aof

当我们重启redis发现无法正常启动,我们使用redis-check-aof工具检查错误

/data # redis-check-aof  /data/appendonlydir/appendonly.aof.1.incr.aof
Start checking Old-Style AOF
AOF /data/appendonlydir/appendonly.aof.1.incr.aof format error
AOF analyzed: filename=/data/appendonlydir/appendonly.aof.1.incr.aof, size=492735, ok_up_to=492723, ok_up_to_line=90906, diff=12
AOF /data/appendonlydir/appendonly.aof.1.incr.aof is not valid. Use the --fix option to try fixing it.
/data # redis-check-aof --fix /data/appendonlydir/appendonly.aof.1.incr.aof
Start checking Old-Style AOF
AOF /data/appendonlydir/appendonly.aof.1.incr.aof format error
AOF analyzed: filename=/data/appendonlydir/appendonly.aof.1.incr.aof, size=492735, ok_up_to=492723, ok_up_to_line=90906, diff=12
This will shrink the AOF /data/appendonlydir/appendonly.aof.1.incr.aof from 492735 bytes, with 12 bytes, to 492723 bytes
y // 输入y才弹出来Continue,然后继续输入y
Continue? [y/N]: Successfully truncated AOF /data/appendonlydir/appendonly.aof.1.incr.aof

修复aof文件后,可以观察到appendonly.aof.1.incr.aof中HELLO WORLD被移除,并可以正常重新启动redis

3. AOF持久化原理

3.1 AOF持久化三大步骤

我们采用伪代码来表示持久化实现的三大步骤:命令追加至aof_buf缓冲区、aof_buf缓冲写入aof文件、fsync文件同步[说白点类似将word中写入的值点击保存至磁盘]

def evenLoop():
    while True:
        // 处理文件事件,接受命令请求以及发送命令回复
        // 处理写请求追加到aof_buf缓冲区
        processFileEvents()
 
        // 处理时间事件
        processTimeEvents()
        
        // 根据持久化策略,也就是appendfsync的配置选择是否将aof_buf缓冲写入并保存到aof文件
        flushAppendOnlyFile()

redis进程就是一个事件循环(loop),循环中的文件事件负责处理客户端请求并响应,当AOF配置appendonly打开时,文件事件处理完写命令后,会将写命令已redis协议格式追加到aof_buf缓冲区末尾【如上图所示】;对于时间事件,则运行定时函数;

3.2 文件写入与同步策略

对于flushAppendOnlyFile()函数,也就是文件写入与同步步骤是由appendfsync配置决定

  • appendfsync everysec: 每个事件循环都要将aof_buf缓冲值写入aof文件,每秒fsync同步至磁盘
  • appendfsync always: 每个事件循环都要将aof_buf缓冲值写入aof文件,并立即fsync同步至磁盘,效率最低,三者中也最安全
  • appendfsync no: 每个事件循环都要将aof_buf缓冲值写入aof文件,由操作系统决定何时 fsync同步至磁盘,一般30s,效率最高,三者中最不安全

4. AOF重写实践与流程

当redis写命令越来越多,aof会越来越大,达到重写配置条件,或者手工执行bgrewriteaof时会触发重写机制已减少aof大小

// AOF重写时不进行fsync操作,防止redis长时间阻塞
no-appendfsync-on-rewrite no
// AOF重写最小大小为64M,当AOF文件大小扩展一倍时触发重写:如128M, 192M
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
4.1 AOF重写实践

我们先记录下.incr.aof文件当前的行数为90805,再次执行上述java批量写入命令,我们发现目前行数增加至181810行,体积变为900K,现在我们执行BGREWRITEAOF重写后,我们发现incr.aof为空了,且base.rdb文件大小由1K增加156K

127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

3
4

4.2 AOF重写流程

当redis版本>=7时,流程如下:

  • redis fork出子进程,此时存在父进程与子进程
  • 子进程开始重写一个新的base aof文件【我们刚重写的是2.base.rdb】到临时文件
  • 父进程打开一个新的incr.aof增量文件【2.incr.aof文件】处理客户端写请求,即使重写失败,manifest文件指向1.base.rdb+2.incr.aof增量文件,所以安全性有保障
  • 当子进程重写完base aof文件,父进程会接收到信号,会使用新的base aof文件和新的incr.aof增量文件来构建一个临时manifest文件,并将manifest、2.base.rdb临时文件持久化
  • redis现在原子性替换manifest文件已使得AOF重写生效,并清理旧的1.base.rdb文件和无用增量文件[1.incr.aof]

当然在低于7版本是通过AOF重写缓冲区实现的,在此不在讨论

5. AOF优缺点

优点:

  • 相对于rdb而言,提供了三种fsync同步策略,数据备份更加安全
  • AOF仅仅追加写命令,不会因为断电寻道导致文件损坏,即使损坏也很容易恢复
  • 当AOF文件过大时,redis能够在后台自动重写
  • AOF协议文本格式易于理解操作,即使flushall删库,只要没有发生重写,仍然可以停止服务器,删除incr.aof中flushall命令,重启数据库来还原

缺点:

  • AOF文件通常比RDB快照文件大
  • AOF数据还原可能比RDB慢,取决于具体fsync策略,禁用fsync策略高负载下也同样和rdb一样快,everysec性能仍然非常高
  • 低于redis7版本时,AOF重写可能会使用大量内存

欢迎关注公众号 算法小生 获取更多精彩内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于真实场景解读 K8s Pod 的各种异常

在 K8s 中&#xff0c;Pod 作为工作负载的运行载体&#xff0c;是最为核心的一个资源对象。Pod 具有复杂的生命周期&#xff0c;在其生命周期的每一个阶段&#xff0c;可能发生多种不同的异常情况。K8s 作为一个复杂系统&#xff0c;异常诊断往往要求强大的知识和经验储备。结合…

骚戴独家笔试---SQL笔试

SQL笔试训练 查询结果去重 两种答案 查找某个年龄段的用户信息 查找除复旦大学的用户信息 三种答案 用where过滤空值练习 三种答案 查询NULL时&#xff0c;不能使用比较运算符(或者< >)&#xff0c;需要使用IS NULL运算符或者IS NOT NULL运算符。 操作符混合运用 我这里…

力扣 792. 匹配子序列的单词数

题目 给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。 字符串的 子序列 是从原始字符串中生成的新字符串&#xff0c;可以从中删去一些字符(可以是none)&#xff0c;而不改变其余字符的相对顺序。 例如&#xff0c; “ace” 是 “abcde” 的子序…

java spring引用外部jar包并使用

spring引用外部jar包并使用1、将jar包放到src/main/resources/lib2、编辑pom.xml文件build下面加入resources&#xff0c;不加话的打包会找不到资源3、project structure中引入该lib1、将jar包放到src/main/resources/lib 2、编辑pom.xml文件 打开pom文件&#xff0c;找到相应…

计算机网络基本知识

计算机网络基本知识 计算机网络定义&#xff1a;是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统。 1.1计算机网络在信息时代作用 1.2因特网概述 1.2.1网络、互联网、因特网 网…

DeepLab V1学习笔记

DeepLab V1摘要相关的工作遇到的问题和解决的方法信号下采样空间不变性(spatial insensitivity/invariance)论文的优点(贡献)网络的模型空洞卷积CRF多尺度预测模型总结实验结果Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs论文地址 : D…

[附源码]java毕业设计乒乓球俱乐部管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【光学】基于Matlab模拟干涉条纹图

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

亿级万物互联新时代的物联网消息中间件EMQX调研

简介 最近去某餐厅吃饭&#xff0c;进门时智能门自动打开房门同时来一句"欢迎光临"&#xff0c;然后伸手到门口的洗手台&#xff0c;水管无接触自动出水&#xff0c;端起菜盘走向台子选择自己喜欢的菜品&#xff0c;最后将菜盘放在智能结账机上&#xff0c;智能结账…

代码随想录算法训练营第三天|LeetCode 203.移除链表元素 、707.设计链表 、206.反转链表

LeetCode 203.移除链表元素 题目链接&#xff1a;203.移除链表元素 链表的定义&#xff1a; // 单链表 struct ListNode {int val; // 节点上存储的元素ListNode *next; // 指向下一个节点的指针ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数 };ListNode(i…

数据结构实验教程-第一套

1&#xff0e;在平衡二叉树中插入一个结点后造成了不平衡&#xff0c;设最低的不平衡结点为A&#xff0c;并已知A的左孩子的平衡因子为1&#xff0c;右孩子的平衡因子为0&#xff0c;则应作_型调整以使其平衡。 A.LL B.LR C.RL D.RR答案为a&#xff0c;错选了c。 平衡因子 左子…

model.py篇

model.py篇 目录如下&#xff1a; 引言找LeNet5网络结构书写代码测试结果函数解释 引言 卷积主要用于特征的提取&#xff0c;而model.py则是为了从输入信息中筛选出我们需要的信息。 我们在阅读完论文后&#xff0c;对我们需要的模型进行搭建&#xff0c;下以LeNet5的model…

子域名访问计数(哈希表、字符串、索引)

力扣地址&#xff1a;力扣 网站域名 "discuss.leetcode.com" 由多个子域名组成。顶级域名为 "com" &#xff0c;二级域名为 "leetcode.com" &#xff0c;最低一级为 "discuss.leetcode.com" 。当访问域名 "discuss.leetcode.com&…

【Struts2】idea快速搭建struts2框架

文章目录什么是SSH框架&#xff1f;Struts2框架1、struts2的环境搭建1.1 创建web项目&#xff08;maven&#xff09;&#xff0c;导入struts2核心jar包1.2 配置web.xml&#xff08;过滤器&#xff09;&#xff0c;是struts2的入口&#xff0c;先进入1.3 创建核心配置文件struts…

力扣(LeetCode)13. 罗马数字转整数(C++)

模拟 罗马数字和掰手指数数的区别在于&#xff0c;IV/IXIV/IXIV/IX 这类倒着数数的&#xff0c;和阿拉伯数字最大的区别在于 555 的 10k10^k10k 倍 k∈Nk\isin Nk∈N &#xff0c;需要被表示出来。所以除了记录 I/X/C/MI/X/C/MI/X/C/M ——1/10/100/10001/10/100/10001/10/100…

五种IO模型

文章目录什么是IO操作系统的IO五种IO模型阻塞IO非阻塞IO多路转接IO(复用IO)信号驱动IO异步IO同步异步什么是IO IO,即input/output,IO模型即输入输出模型,而比较常见且听说的便是磁盘IO,网络IO. 按照冯诺依曼结构的来看,假设我们把运算器、控制器、存储器三个设备看做一个整体…

Kruskal算法求最小生成树

输入样例&#xff1a; 4 5 1 2 1 1 3 2 1 4 3 2 3 2 3 4 4输出样例&#xff1a; 6适用于稀疏图&#xff0c;快&#xff1b; 实现步骤&#xff1a; 1.将所有边将权重从小到大排序&#xff1b;sort&#xff1b;O&#xff08;mlogm&#xff09; 2.枚举每条边a,b&#xff1b;权…

RabbitMQ的 AMQP协议都是些什么内容呢

之前也讲述过关于 RabbitMQ 的相关内容&#xff0c;比如他们的配置&#xff0c;以及 RabbitMQ 整合 SpringBoot 使用&#xff0c;而且自己使用过之后&#xff0c;就会在自己的简历上面写上自己使用 RabbitMQ 实现了什么功能&#xff0c;但是这就会导致&#xff0c;有些面试官就…

QPainter、QPen 、QBrush(概念)

Qt中的三大绘画类&#xff1a; QPainter :进行绘画QPaintDevice :提供画图设备&#xff0c;是一个二维的抽象&#xff08;是所有可绘制对象的基类&#xff09;QPaintEngine :提供了画家用于绘制到不同类型的设备上的界面QPainter(画家) QPainter 提供高度优化的功能来完成 GUI …

Presto 聚合中groupBy分组的实现

一.前言 本文只要探索在Presto中groupby是怎么实现的。在Preso中&#xff0c;groupby的分组主要通过对数据Hash的数值比较进行分组&#xff0c;其中有2种情况&#xff0c;一直是仅有一个groupby字段而且字段是Bigint类型的&#xff0c;此场景下会使用BigintGroupByHash来实现分…