消息中间件之RocketMQ源码分析(二十三)

Broker的关机恢复机制

概述

Broker关机恢复是指恢复CommitLog、Consume Queue、Index File等数据文件。Broker关机分为正常调用命令关机和异常被迫进程终止关机两种情况。恢复过程的设计目标是使正常停止的进程实现零数据丢失,异常停止的进程实现最少量的数据丢失,与关机恢复相关的主要文件有两个:abort和checkpoint.

abort文件

abort是一个空文件,标记当前Broker是否正常关机,Broker进程正常启动的时候,创建该文件。Broker进程正常停止后,该文件就会删除;如果异常退出,则文件依旧存在,创建和删除的过程如图

  • abort文件创建流程
    在这里插入图片描述
  • aboirt文件删除流程
    在这里插入图片描述

Checkpoint文件

checkpoint是检查点文件,保存Broker最后正常存储各种数据的时间,在重启Broker时,恢复程序知道从什么时候恢复数据。检查点逻辑由StoreCheckpoint类实现。
在StoreCheckpoint类中保存了3个时间,更新过程如图.
在这里插入图片描述

  • physicMsgTimestamp:最后一条已存储CommitLog的消息的存储时间
  • logicsMsgTimestamp:最后一条已存储Consume Queue的消息的存储时间
  • indexMsgTimestamp:最后一条已存储IndexFile的消息的存储时间
  • physicMsgTimestamp和logicsMsgTimestamp的更新都是在数据存储成功后进行的,过程比较简单。而indexMsgTimestamp的逻辑是在Index File刷盘时被更新的,Index File刷盘方法IndexService.flush()。

在这里插入图片描述

从上述代码可以看到,在IndexFile刷盘后,已刷盘文件文件的最后存储消息时间被赋值给indexMsgTimestamp,并对Checkpoint文件进行刷盘。
注:IndexFile的刷盘设计和CommitLog、Consume Queue刷盘的方式不同,容易被忽略

Broker关机恢复流程

Broker在启动时会初始化abort、checkpoint两个文件。正常关闭进程时会删除abort文件,将checkpoint文件刷盘;异常关闭时,通常来不及删除abort文件。由此,在重新启动Broker时会根据abort判断是否需要异常停止进程,而后恢复数据。Broker启动时,会启动存储服务DefaultMessageStore.存储服务在初始化时执行load方法加载全部数据,这里主要分析数据加载流程。Broker关机的恢复过程可以分为以下几步.
在这里插入图片描述

  • 第一步:Broker异常退出检查。如果abort文件存在,说明上次是异常退出的。
  • 第二步:加载延迟消息的位点信息。ScheduleMessageService服务通过继承和重写ConfigManager,调用load()方法从磁盘加载延迟位点文件的内容,并根据配置项messageDelayLevel初始化延迟级别
  • 第三步:加载全部CommitLog文件(#1部分)。通过读取CommitLog目录下的所有文件,依次加载每个CommitLog为MappedFile,并且设置写指针、已刷盘指针、已提交指针,使所有指针都指向该文件的最末位.CommitLog文件加载代码如图。如果文件大小已配置的大小不一致,恢复时
    就直接被忽略,所以,在重启时不要修改mappedFileSizeCommitLog(默认是1G)参数的值,否则数据无法恢复

在这里插入图片描述

  • 第四步:加载全部Consume Queue文件及数据(如图#2、#3)。调用loadConsumeQueue方法,读取./consumequeue/Topic/queueId/目录,加载全部Topic、queueId作为ConsumeQueue对象,再调用load()方法初始化每一个ConsumeQueue
    在这里插入图片描述
  • 第五步:初始化Checkpoint文件为StoreCheckpoint对象,并且初始化三个数据:physicMsgTimestamp、logicsMsgTimestsamp和indexMsgTimestamp.
    初始化StoreCheckpoint对象
    在这里插入图片描述
    在StoreCheckpoint构造方法中初始化三个时间戳
    在这里插入图片描述
  • 第六步:加载IndexFile索引(#4部分)。加载./index目录下的全部索引文件,如果上次进程异常退出并且索引文件操作的最后时间戳大于Checkpoint中保存的时间,则说明当前文件有部分数据可能存在错误,须立即销毁文件
  • 第七步:恢复全部数据(#5部分)lastExitOK=True,表示上次进程正常退出。全部恢复数据主要恢复ConsumeQueue、CommitLog、内存中的consumeQueueTable,并纠正Consume Queue中的最新位点值。
    在这里插入图片描述
    recoverCOnsumeQueue()方法通过循环所有Topic对应的ConsumeQueue,依次调用ConsumeQUeue.recover()方法执行数据恢复
    在这里插入图片描述
    recoverNormally()方法在Broker正常关闭后重启执行CommitLog恢复(#5,2)对于CommitLog恢复数据,这里有一个小技巧,正常恢复是从倒数第三个文件开始直到最后一个文件。正常恢复是假定数据都是正常的,大部分场景都关心最新的消息,所以恢复最新的三个文件到内存中,消息量大小为3GB,当然,如果恢复文件个数做成可配置的就更好了
    在这里插入图片描述
    recoverAbnormally()方法在Broker异常关闭后重启时执行CommitLog恢复(#5.3)CommitLog异常恢复是从最后一个文件开始反向恢复到第一个文件。因为当进程异常停止后最容易出错的是最新的某些文件。所以异常恢复时,RocketMQ从最后一个文件开始,倒序找第一个正常的文件开始恢复。

CommitLog.isMappedFileMatchedRecover()方法判断文件是否正常,整个方法的重点在于,只要文件的最后消息的存储时间都小于在Checkpoint保存的对应时间,那么该文件并未损坏。

CommitLog恢复完毕,会将该文件中的消息重新分发,创建ConsumeQueue和IndexFile。分发全部消息还是部分消息时根据duplicationEnable的值(默认为False)来判断的
在这里插入图片描述
recoverTopicQueueTable():纠正Consume Queue中最小消费位点和恢复ComitLog内存中的TopicTable(#5.4)
在这里插入图片描述

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

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

相关文章

Java 数据库面试题解析(中)

10. 事务并发引发的问题?【重点】 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。 不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了…

Groovy - 大数据共享搜索配置

数据共享搜索列中配置了搜索列,相应的数据共享接口中也需要支持根据配置的字段搜索,配置实体时,支持搜索的入参code必须是searchKeys,且接口应该是需要支持分页(入参必须是 current、pageSize)的。current …

Linux系统Docker部署Nexus Maven并实现远程访问本地管理界面

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具,用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关,可…

SpringBoot多数据源配置(MySql、Oracle)

一、依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId></dependency><!--oracle驱动--><dependency><groupI…

JavaScript高级程序设计

前言 《JavaScript高级程序设计》 第1章——什么是JavaScript DOM将整个页面抽象为一组分层节点。 BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript 2.1 < script >元素 元素描述async立即开始下载脚本&#xff0c;但不能阻止其他页面动作&#…

深圳智能制造半导体芯片行业源代码防泄密完整解决方案

一、芯片半导体行业防泄密&#xff0c;不能用监控及管控方式来实现&#xff0c;采用管控方式&#xff0c;首先不能主动防御&#xff0c;只能进行事后查询&#xff0c;并且管控方式&#xff0c;不利于嵌入式开发&#xff0c;对于嵌入式开发&#xff0c;不管是采用沙箱隔离或u口禁…

linux查看服务器内核CUP版本相关命令

服务器参考 计算架构&#xff1a;x86-64产品系列&#xff1a;华为云耀云服务器操作系列&#xff1a;CentOS 7 执行uname -a查看服务器内核版本 Linux hecs-82210 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux执行hostn…

Vue动态缓存KeepAlive

vue中keep-alive组件主要有三个常用的props。 1&#xff0c;include存放的name是组件自身的name属性&#xff0c;只有名称匹配的组件会被缓存2&#xff0c;exclude&#xff0c;任何名称匹配的组件都不会被缓存3&#xff0c;max&#xff0c;最多可以缓存多少组件实例&#xff0…

delete误删基表(seg$)bbed恢复cluster table

有客户通过delete误删了sys.seg$表的数据&#xff0c;重启数据库&#xff0c;发现数据库不能正常启动。 删除命令&#xff1a;delete from sys.seg$ t where ts#2; 数据库启动报错 Errors in file /u01/app/diag/rdbms/orcl/orcl/trace/orcl_ora_48064.trc (incident325391)…

【蓝桥杯入门记录】动态数码管例程

目录 &#xff08;1&#xff09;例程1&#xff1a;两个数码管显示不同内容。本例以第一个数码管显示数字“0”&#xff0c;第二个数码管显示数字“1”为例。 &#xff08;2&#xff09;例程2&#xff1a;多个数码管显示不同内容&#xff08;二&#xff09;。注&#xff1a;创建…

HarmonyOS 开发之———应用程序入口—UIAbility的使用

谢谢关注!! 前言:上一篇文章主要介绍ArkJS 基础—〉自定义组件使用。如需了解谢谢查阅:http://t.csdnimg.cn/01PQ2 一、UIAbility概述 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。 …

掌握结构化日志记录:全面指南

在当今复杂的软件生态系统中&#xff0c;应用程序日志非常宝贵。它们允许开发者窥视应用程序的内部&#xff0c;了解系统内部的真实情况。但是&#xff0c;传统的非结构化日志数据有很多不足之处。这些混乱的文本块无法提供完整的画面。要真正发挥日志的力量&#xff0c;我们需…

浅析扩散模型与图像生成【应用篇】(三)——RDDM

3. Residual Denoising Diffusion Models 该文提出一种残差去噪扩散模型&#xff08;RDDM&#xff09;可用去图像生成和图像修复&#xff08;如去除阴影、去雨、暗光提升等&#xff09;。该文最大的特点是提出一种双扩散模型&#xff0c;在扩散过程中不仅包含噪声 ϵ \epsilon …

Windows WMI详解

WMI简介 WMI ( Windows Management Instrumentation, Windows管理规范)是Windows 2000/XP管理系统的核心&#xff0c;属于管理数据和操作的基础模块。设计WMI的初衷是达到一种通用性&#xff0c;通过WM操作系统、应用程序等来管理本地或者远程资源。它支持分布式组件对象模型(…

select * from 表 c=‘1‘ and b=‘2‘ and a=‘3‘; abc是联合索引,这样查询会命中索引吗?

倒叙也会命中索引 但是要注意&#xff0c;倒叙的时候必须要有a存在&#xff0c;否则就会索引失效 因为mysql底层会有优化器去进行优化&#xff0c;但是如果没有a的话&#xff0c;那么优化器就不知道要优化那个索引了&#xff0c;所以他走了全表&#xff0c;导致索引失效

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…

【Rust详细学习路线】讲解

Rust详细学习路线 1. 介绍2. 初学者阶段3. 进阶阶段4. 深入研究阶段 1. 介绍 学习Rust编程语言可以采取分阶段的方法来确保全面掌握其特色和细节&#xff0c;以下是Rust的一个详细学习路线&#xff0c;你可以根据个人学习进度做适当的调整&#xff1a; 2. 初学者阶段 了解Rus…

Redis数据类型--List类型详解及应用

数据结构 Redis无论什么数据类型&#xff0c;存储的时候都是以键值对key-value形势存储&#xff0c;并且所有的key都是String类型&#xff0c;本文讨论的数据类型是value的数据类型。 List类型 概述&#xff1a;list类型可以存储一个有序的字符串列表&#xff0c;为了方便理…

Tomcat服务部署

1、安装jdk、设置环境变量并测试 第一步&#xff1a;安装jdk 在部署 Tomcat 之前必须安装好 jdk&#xff0c;因为 jdk 是 Tomcat 运行的必要环境。 1. #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02. #将安装 Tomcat 所需软件包传到/opt…

备战蓝桥杯Day20 - 堆排序的实现

一、每日一题 蓝桥杯真题之互质数的个数 我的解法&#xff1a; 两个数互质&#xff0c;说明两个数的最大公约数是1&#xff0c;定义了一个函数判断两个数的最大公约数&#xff0c;再在循环中判断&#xff0c;并实现计数。可以实现运行&#xff0c;缺点是时间复杂度很高&#…