正常恢复和异常恢复|学习笔记

简介: 快速学习正常恢复和异常恢复

开发者学堂课程【RocketMQ 知识精讲与项目实战(第三阶段)正常恢复和异常恢复】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/704/detail/12487


正常恢复和异常恢复


内容介绍:

一.正常恢复

二.异常恢复

一.正常恢复


两种恢复的机制。第一种是正常恢复,在恢复的时候,并没有从第一个文件去恢复。是从倒数第三个开始恢复。正常退出的时候,数据基本上是同步的。从拿到第三文件的索引 index ,就开始进行恢复。在恢复的时候,首先去把 mappedFile 这个文件拿出来,再根据它获得 byteBuffer ,然后拿到上一次处理的位置 processOffset 。pub1ic void recoverNormally(long maxPhyOffsetofConsumeQueue) {
final List<MappedFile> mappedFiles = this . mappedFileQueue . getMappedFiles();
if (!mappedFiles. isEmpty()) {
// Broker 正常停止再重启时,从倒数第三个开始恢复,如果不足3个文件,则从第一个文件开始恢复。
int index = mappedFiles.size() - 3;
if (index < 0)
index = 0;
MappedFile mappedFile = mappedFiles . get(index);
ByteBuffer bytBuffer = mappedFile. sliceByteBuffer();
long processoffset = mappedFile. getFileFromoffset();
//代表当前已校验通过的 offset
1ong mappedFileOffset = 0;

先去查找  byteBuffer 当中的消息。取出消息的长度,判断消息的长度如果查找的结果为 ture ,并且消息长度大于0,表示消息正确,已经同步过的消息,不需要去进行对应的处理。然后当前消息的偏移量 mappedFileOffset 往后移除当前消息长度就可以了。

如果查找结果为 true 且消息长度等于0,说明已经检测到消息的末尾。如果还有下一个文件就取出下一个文件,重置 processOffset 和 MappedFileOffset 。

while (true) {
//查找消息       DispatchRequest dispatchRequest = this. checkMessageAndReturnsize (byteBuffer,checkCRConRecover);
//消息长度
int size = dispatchRequest. getMsgsize();
//查找结果为 true ,并且消息长度大于0,表示消息正确 . mappedFileoffset 向前移动本消息长度
if (dispatchRequest. Issuccess() && size > 0) {
mappedFileoffset += size;
}
//如果查找结果为 true 且消息长度等于0,表示已到该文件末尾,如果还有下一个文件,则重置 processoffset 和 MappedFileoffset 重复查找下一个文件,否则跳出循环。

else if (dispatchRequest. IsSuccess() && size== 0) {
index++;
if (index >= mappedFiles.size() {

// Current branch can not happen
break;
} else {
//取出每个文件
mappedFile = mappedFiles. get(index);
byteBuffer = mappedFile. sliceByteBuffer();
processoffset = mappedFile. getFileFromoffset();

mappedFileoffset = 0;
}

}

如果查找结果为 false ,说明这个文件还未被填满,直接跳出循环,结束循环。

//查找结果为 false ,表名该文件未填满所有消息,跳出循环,结束循环。

else if (!dispatchRequest. issuccess()) {

1og. info("recover physics file end, " + mappedFile. getFileName());

break;

}

}

更新 MappedFileQueue 的 flushedWhere 和 committedWhere 指针。

//更新 MappedFileQueue 的 flushedWhere 和 committedWhere 指针

processoffset += mappedFileoffset;
this. mappedFileQueue . setFlushedwhere (processoffset);

this. mappedFileQueue . setCommi ttedwhere(processoffset);

整个的这些如果都恢复完了之后,紧接着就是将 offset 之后的所有文件删除。

//删除 offset 之后的所有文件
this . mappedFileQueue . truncateDi rtyFiles (processoffset);
if (maxPhyoffsetofconsumeQueue , = processoffset) {
this. defaultMessageStore. truncateDi rtyLogicFiles (processoffset);

}
} else {
this . mappedFileQueue . setFlushedwhere(0);

this . mappedFileQueue . setCommittedwhere(0) ;

this. defaultMessagestore. destroyLogics();

}

}

整个恢复逻辑在 recoverNormally 方法当中。

二、异常恢复

相比正常恢复,异常恢复实现的逻辑就在 recoverAbnormally 里面去处理。异常文件恢复步骤与正常停止文件恢复流程基本相同,主要的差别有两个。首先,正常默认从倒数第三个文件开始恢复,而异常文件停止则需要从最后一个文件往前走,找到第一个消息存储正常的文件。其次,如果 CommitLog 目录没有消息文件,如果消息消费队列目录下存在文件,则需要销毁。

异常恢复所对应的位置

if (!mappedFiles. isEmpty()) {
// Looking beginning to recover from which file
int index = mappedFiles .size() - 1;
MappedFile mappedFile = null;
for (; index >= 0; index--) {
mappedFile = mappedFiles. get(index);

发现index - 1 ,说明从最后一个文件去进行恢复处理。

然后判断消息文件是否是一个正确的文件,从正常的文件开始慢慢地去恢复。根据索引取出 mappedFile 文件,去进行一个恢复的处理,

//判断消息文件是否是一个正确的文件
if (this. isMappedFileMatchedRecover (mappedFile)){
1og. info("recover from this mapped file " + mappedFile. getFileName());
break;

}
}
//根据索引取出 mappedFile文件
if (index < 0) {
index = 0;
mappedFile = mappedFiles . get(index);
}
//...验证消息的合法性,并将消息转发到消息消费队列和索引文件

} else {
//未找到 mappedFile ,重置 flushwhere 、 commi ttedwhe re 都为0,销毁消息队列文件
this. mappedFi lequeue. setFlushedwhere(0);
this. mappedFi lequeue. setCommi ttedwhere(0) ;
this. defaultMessagestore. destroyLogics();

}

正常恢复和异常恢复主要的区别,正常恢复是从倒数第三个,异常恢复是从倒数第一个开始去处理。

相关文章
|
6月前
|
机器学习/深度学习 传感器 数据采集
基于机器学习的数据分析:PLC采集的生产数据预测设备故障模型
本文介绍如何利用Python和Scikit-learn构建基于PLC数据的设备故障预测模型。通过实时采集温度、振动、电流等参数,进行数据预处理和特征提取,选择合适的机器学习模型(如随机森林、XGBoost),并优化模型性能。文章还分享了边缘计算部署方案及常见问题排查,强调模型预测应结合定期维护,确保系统稳定运行。
648 0
|
11月前
|
SQL 安全 数据挖掘
牛客网刷题之SQL篇:非技术快速入门39T
这篇文章是关于牛客网上的SQL刷题教程,涵盖了基础的SQL运算符和多个实际的数据分析场景,旨在帮助非技术人员快速入门SQL。
608 0
牛客网刷题之SQL篇:非技术快速入门39T
|
Prometheus 监控 Cloud Native
使用mysqld_exporter监控所有MySQL实例
使用mysqld_exporter监控所有MySQL实例
1105 2
|
10月前
|
前端开发 Java 数据库连接
你不可不知道的JAVA EE 框架有哪些?
本文介绍了框架的基本概念及其在编程领域的应用,强调了软件框架作为通用、可复用的软件环境的重要性。文章分析了早期Java EE开发中使用JSP+Servlet技术的弊端,包括可维护性差和代码重用性低等问题,并阐述了使用框架的优势,如提高开发效率、增强代码规范性和可维护性及提升软件性能。最后,文中详细描述了几种主流的Java EE框架,包括Spring、Spring MVC、MyBatis、Hibernate和Struts 2,这些框架通过提供强大的功能和支持,显著提升了Java EE应用的开发效率和稳定性。
566 1
|
存储 数据库
zookeeper 集群环境搭建及集群选举及数据同步机制
zookeeper 集群环境搭建及集群选举及数据同步机制
345 2
|
Linux 网络安全 iOS开发
如何在Python中使用Pip换源
如何在Python中使用Pip换源
|
数据安全/隐私保护 索引 Python
“从零开始学习Python包开发:掌握Setuptools工具的使用“
“从零开始学习Python包开发:掌握Setuptools工具的使用“
|
SQL 关系型数据库 MySQL
MySQL:Access denied for user &#39;root&#39;@&#39;localhost&#39;
mysql数据库对权限校验也是特别的严格的,毕竟数据安全是很重要的,那么,像我这种小白用户就会遇到很多像权限不足,或者无法连接数据库的尴尬境遇,那么,假如遇到题中所述的问题如何解决呢?下面请看小白的解决方案!
1467 0
|
监控 关系型数据库 MySQL
CentOS 7系统安装配置Zabbix 5.0LTS 步骤
CentOS 7系统安装配置Zabbix 5.0LTS 步骤 查看Zabbix官方教程(重点) 打开官方网址:https://www.zabbix.com/cn,点击ZABBIX下载。 选择你的Zabbix服务器的平台,比如:Zabbix5.0 LTS、CentOS 7、Mysql、Apache等。 往下滑,查看安装和配置Zabbix教程
853 1
|
消息中间件 RocketMQ Docker
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)(上)
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
358 0