RocketMQ源码学习笔记:Broker启动流程

news2025/2/3 10:48:08

这是本人学习的总结,主要学习资料如下

  • 马士兵教育
  • rocketMq官方文档

目录

  • 1、Broker启动流程
  • 2、一些重要的类
    • 2.1、MappedFile
    • 2.2、MessgeStore
    • 2.3、MessageStore的加载启动流程
  • 3、技术亮点
    • 3.1、 内存映射
      • 3.1.1、简介
      • 3.1.2、源码

1、Broker启动流程

Broker启动流程与NameServer的几乎一样,都是先读取外部配置并利用外部配置创建出BrokerController

接着使用创建好的BrokerController,在其initialize()方法中创建运行启动时必要的实例。

之后再start()方法中开启网络和持久化服务。

流程如下所示。

在这里插入图片描述


2、一些重要的类

在这里插入图片描述
以上是Broker中比较重要的类,他们被分成三个层次。

业务层是用于处理发送和接受信息,他们会调用逻辑存储层的对象获取基础一些的服务。

逻辑存储层的类可以看成是代表着Broker里的文件或者文件夹的,比如CommitLog这个类就代表着存储消息详细信息的commitlog文件夹;ConsumeQueue则代表存储消息队列的comsumequeue

存储I/O层里则是Broker里最贴近底层的类,比如MappedFile代表着某一个文件。

2.1、MappedFile

MappedFile代表着一个物理文件。

它是对File类的一个包装,底层还是用File访问磁盘文件。不过MappedFile增加了一些功能,比如增加了wrotePosition这个成员,代表着下次写文件时,系统可以直接通过wrotePosition知道文件的末尾在哪,这样就可以直接写入文件。

在这里插入图片描述

2.2、MessgeStore

MessageStore是用于读写存储文件的一个类。这里的存储文件是指CommitLogcomsumeQueue这些文件。

源码中使用它的实现类DefaultMessageStore,通过load()方法完成初始化,之后在开启服务的start()方法中通过start()方法开启服务。

所以MessageStore是管理存储文件的一个类。源码中还有多个和它类似的成员,他们负责不同的功能,但都是load()初始化,start()开启服务。


2.3、MessageStore的加载启动流程

MessageStore的启动加载包含了很多很多服务,比如CommitLogConsumeQueue等。但他们的加载启动都大同小异,所以这里只选了CommitLog讲解。

MessageStoreBrokerController的一个成员变量。它在BrokerController中的initialize()完成实例初始化,随后调用其load()方法更进一步地加载具体的服务。以下是涉及到的代码片段。

在这里插入图片描述


以这个线索来看CommitLog加载的具体内容,messageStore.load() -> commitLog.load() -> doLoad()

可以看出所谓的加载,就是访问/store/commitlog下的所有文件,将他们包装成MappedFile存起来,方便后续的访问。

3、技术亮点

3.1、 内存映射

3.1.1、简介

MappedFileBroker中可以说是最底层的代表文件的类,它使用了内存映射技术大大加快了文件的读写速度。

下面是网络数据到磁盘的过程。

在这里插入图片描述
一般的IO会有四次复制,两次DMA拷贝,两次CPU拷贝。

CPU拷贝的效率要慢很多,一般来说200M的数据,DMA拷贝仅需2ms,而CPU拷贝需要200ms。所以200M的数据从网络设备缓冲区到磁盘用传统的IO需要404ms

内存映射技术是建立一个磁盘空间和内存空间的映射通道,会覆盖一片磁盘空间,最大是1.5G ~ 2G

当我们向被覆盖的内存空间写数据时,数据可以通过通道到达磁盘。这种方式允许DMA直接从内存拷贝数据到磁盘。

所以应用内存映射技术后,数据从网络设备缓冲区到磁盘就只需要一次CPU拷贝,两次DMA拷贝。200m的数据只需要204ms,是传统IO的一半。

因为内存映射最多只能覆盖1.5G ~ 2G的磁盘空间,所以commitlog的文件最大是1G,保证每次映射能完整覆盖一个文件。


3.1.2、源码

内存映射的代码是放在MappedFile中,在BrokerController.initialize()阶段建立各个文件的内存映射通道。可根据一下的线索看到源码。

start() -> createBrokerController() -> controller.intialize() -> messageStore.load() -> commitLog.load() -> mappedFileQueue.load() -> doLoad() -> new MappedFile() -> init()

所以MappedFile在实例初始化时就会建立内存映射通道,以下是构造方法调用的init()的关键内容。

private void init(final String fileName, final int fileSize) throws IOException {
    this.file = new File(fileName);
    try {
    	// rw表示允许读写
        this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
        this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
        TOTAL_MAPPED_VIRTUAL_MEMORY.addAndGet(fileSize);
        TOTAL_MAPPED_FILES.incrementAndGet();
        ok = true;
    } catch (FileNotFoundException e) {
        log.error("Failed to create file " + this.fileName, e);
        throw e;
    } finally {
        if (!ok && this.fileChannel != null) {
            this.fileChannel.close();
        }
    }
}

可以看到,它通过new RandomAccessFile(this.file, "rw").getChannel()创建文件的内存通道,并且赋值给fileChannel。即使没有看其他的源码也可以知道,之后涉及到文件的读写操作最后一定会先获取这个fileChannel,再调用其中的read(),write()等方法进行读写。

其中还有一个叫mappedByteBuffer的成员变量,它代表着被映射的磁盘空间。

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

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

相关文章

Java IO模型BIO、NIO、AIO介绍

第一章 BIO、NIO、AIO课程介绍 1.1 课程说明 在java的软件设计开发中,通信架构是不可避免的,我们在进行不同系统或者不同进程之间的数据交互,或者在高并发下的通信场景下都需要用到网络通信相关的技术,对于一些经验丰富的程序员来…

envi5.6+SARscape560安装(CSDN_20240623)

envi和SARscape的版本必须匹配,否则有些功能不能使用。 Envi5.6安装 1. 点击安装程序. 2. 进入安装界面,点击“Next”. 3. 选择“I accept the agreement”,点击“Next”。 4. 选择安装路径,建议直接安装在默认路径下&#xff0…

深入解析 iOS 应用启动过程:main() 函数前的四大步骤

深入解析 iOS 应用启动过程:main() 函数前的四大步骤 背景描述:使用 Objective-C 开发的 iOS 或者 MacOS 应用 在开发 iOS 应用时,我们通常会关注 main() 函数及其之后的执行逻辑,但在 main() 函数之前,系统已经为我们…

【IC验证】UVM实验lab04

1. driver和sequencer之间的通信 task do_drive()chnl_trans req, rsp;(posedge intf.rstn);forever beginseq_item_port.get_next_item(req);this.chnl_write(req);void($cast(rsp, req.clone()));rsp.rsp 1;rsp.set_sequence_id(req.get_sequence_id());set_sequence.item_…

数据库原理与安全复习笔记

1 概念 产生与发展:人工管理阶段 → \to → 文件系统阶段 → \to → 数据库系统阶段。 数据库系统特点:数据的管理者(DBMS);数据结构化;数据共享性高,冗余度低,易于扩充&#xff…

YOLOv10目标检测算法的使用

目录 一、环境安装 1、创建虚拟环境 2、安装依赖 二、数据集准备 1、预训练权重 2、数据划分 3、建立数据集的yaml文件 三、训练 1、终端运行指令 2、建立一个 python 文件运行 四、验证 1、终端运行指令 2、建立一个 python 文件运行 五、模型推理 1、单张图片推…

C语言之详解预处理

前言: 预处理也叫预编译,是编译代码时的第一步,经过预处理后生成一个.i文件,如果不明白编译与链接作用的小伙伴可以先看看博主的上一篇博客—— ,不然知识连贯性可能会显得很差哦。 正文目录: 预定义符号#…

Redis 入门篇

文章目录 Redis简介关系型数据库:非关系型数据库 Redis应用场景Redis下载和安装Redis 数据类型Redis 常用命令字符串 string 操作命令哈希 hash 操作命令列表 list 操作命令集合 set 操作命令有序集合 sorted set 操作命令通用命令 Jedis 快速入门配置依赖建立连接 / 操作 Jedi…

Android蓝牙开发(一)之打开蓝牙和设备搜索

private BluetoothManager bluetoothmanger; private​ BluetoothAdapter bluetoothadapter; /** 判断设备是否支持蓝牙 */ bluetoothmanger (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothadapter bluetoothmanger.getAdapter(); if (bl…

element-ui里message抖动问题

由于element默认屏蔽滚动条,导致取消时弹message时 侧边滚动栏突然回来后引起抖动问题 是由于打开弹窗时出现遮罩层dialog对话框 时引起了元素内容超出自身尺寸 对应的overflow样式内容为hidden,且新建了一个class类内容为增加17 内右边距,当…

一文详解分布式 ID

分布式系统中,我们经常需要对数据、消息等进行唯一标识,这个唯一标识就是分布式 ID,那么我们如何设计它呢?本文将详细讲述分布式 ID 及其生成方案。 一、为什么需要分布式 ID 目前大部分的系统都已是分布式系统,所以在…

python实训day2

1、 from ming import * # 有点像C语言中的头文件 """在Python开发环境中,封装一个函数,功能目标为:通过两个整数参数一次性获取和、差、积、商四个值 """ def calc(a, b):return a b, a - b, a * b, a / b…

使用SPI驱动数码管

代码&#xff1a; 7-seg.c /*《AVR专题精选》随书例程3.通信接口使用技巧项目&#xff1a;改进的延时法实现半双工软件串口文件&#xff1a;7seg.c说明&#xff1a;SPI控制数码管驱动文件作者&#xff1a;邵子扬时间&#xff1a;2012年12月15日*/#include <avr/io.h>ex…

AIGC时代的英语教育:人工智能会取代英语老师吗?

在当前AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;时代&#xff0c;人工智能技术正在迅速发展并渗透到各个领域&#xff0c;其中包括英语教育。面对这一趋势&#xff0c;许多人担心人工智能会取代传统的英语教师。然而&#xff0c;本文将探讨人工智…

Android 天气APP(八)城市切换 之 自定义弹窗与使用

然后在模块的utils包中新建一个LiWindow类 代码如下&#xff1a; package com.llw.mvplibrary.utils; import android.app.Activity; import android.content.Context; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; im…

GitHub 标星 6

美国网友对这个大全给予了很高的评价&#xff1a;这份清单中列出的开源软件&#xff0c;不仅解决了硅谷大厂前员工的难处&#xff0c;也能为其他所有码农解除困惑。 在这套大全的指导下&#xff0c;任何一个工程师&#xff0c;都能获得类似在谷歌内部写代码的体验。xg2xg 上线…

【Flutter 专题】120 Flutter 腾讯移动通讯 TPNS~

1.2 方法使用 小菜按照官网的介绍尝试了一些常用的 API 方式&#xff0c;主要分为应用类&#xff0c;账号类和标签类三种 API&#xff0c;小菜业务中没有应用账号和标签模块&#xff0c;暂未深入研究&#xff1b; 应用接口 API a. 注册推送服务 对于服务的注册初始化&#x…

软件串口接收子程序

代码; stduart.c /*《AVR专题精选》随书例程3.通信接口使用技巧项目&#xff1a;使用延时法实现半双工软件串口文件&#xff1a;sfuart.c说明&#xff1a;软件串口驱动文件作者&#xff1a;邵子扬时间&#xff1a;2012年12月13日*/ #include "sfduart.h"// 循环中延…

数据结构历年考研真题对应知识点(栈)

目录 3.1栈 3.1.1栈的基本概念 【栈的特点&#xff08;2017&#xff09;】 【入栈序列和出栈序列之间的关系(2022)】 【特定条件下的出栈序列分析(2010、2011、2013、2018、2020)】 3.1.2栈的顺序存储结构 【出/入栈操作的模拟(2009)】 3.1栈 3.1.1栈的基本概念 【栈…

嵌入式linux系统中LCD屏驱动实现思路分析

在 Linux 下 LCD 的使用更加广泛,在搭配 QT 这样的 GUI 库下可以制作出非常精美的 UI 界面。接下来就来学习一下如何在 Linux 下驱动 LCD 屏幕。 第一:Framebuffer设备简介 先来回顾一下裸机的时候 LCD 驱动是怎么编写的,裸机 LCD 驱动编写流程如下: ①、初始化 I.MX6U 的…