同步刷盘分析|学习笔记

简介: 快速学习同步刷盘分析

开发者学堂课程【RocketMQ 知识精讲与项目实战(第三阶段)同步刷盘分析】学习笔记,与课程紧密联系,让用户快速学习知识。

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


同步刷盘分析

 

同步刷盘

RocketMQ 的存储是基于 JDK NIO 的内存映射机制(MappedByteBuffer)的,消息存储首先将消息追加到内存,再根据配置的刷盘策略在不同时间进行刷写磁盘。再根据刷盘的策略来决定到底是同步刷盘还是异步刷盘。

消息追加的入口在 CommitLog 中有个 putMessages 里。前面做的都是将数据追加到内存里去,再根据不同的刷盘策略,再去将数据刷到磁盘当中。

image.png

handleDiskFlush(result,putMessageResult,messageExtBatch);//刷盘入口

进入到putMessageResult。先判断 MessageStoreConfig 当中刷盘的策略。SYNC_FLUSH 是同步刷盘。

同步刷盘的意思是消息追加到内存后,立即将数据刷写到磁盘文件。同步刷盘的逻辑是这样的。

finalGroupCommitService service = (GroupCommitService) this.flushCommitLogService;

//拿到同步刷盘的服务 GroupCommitService ,

GroupCommitRequest request = new

GroupcommitRequest(nextOffset:result.getWroteOffset() +

result.getWroteBytes());

//创建刷盘的请求对象 GroupCommitRequest

service.putRequest(request); //将请求对象提交到 service ,在 service 当中进行了处理

boolean flushOK =

request.waitForFlush(this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout());

// waitForFlush 这个请求等待刷盘的结果。

private int syncFlushTimeout =1000 * 5;

// 等待超时时间 getSyncFlushTimeout 为5秒,就是会同步阻塞5秒。

把 request 提交到 service.putRequest 当中, service 用了等待唤醒机制去进行一个处理。

public synchronized void putRequest(final GroupCommitRequest request){

synchronized (this.requestsWrite) {

this.requestsWrite.add(request);

}

if (hasNotified.compareAndSet(expect:false,update:true)){

waitPoint.countDown(); //唤醒线程notify

}

这里首先是把这个请求去附着到一个集合当中,

private volatile List<GroupCommitRequest> requestsWrite = new ArrayList<~>(); //写集合

private volatile List<GroupCommitRequest> requestsRead = new ArrayList<~>(); //读集合

首先将 request 对象放到 requestsWrite 当中去,然后在处理的时候,为了提高读写的效率,将数据会复制到 requestsRead 中去,然后前后分开去处理。我们将请求对象提交到 requestWrite 这个集合当中,这里面唤醒了一下这个线程 notify 。

线程唤醒之后看run 方法,run 方法最核心地方在 doCommit ,处理请求的时候,会间隔10毫秒去处理一次,有请求就会去处理。

while  (!this.isStopped()) {

try {

this.waitForRunning( interval: 10);//处理请求间隔10毫秒

this.doCommit(); //run 方法核心

} catch (Exception e) {

CommitLog.Log.warn(this.getserviceName() + " service has exception. ", e);

}

}

在处理的时候,把 While循环开启,然后在下边去做一个 swapRequests 方式

private void swapRequests() {

List<GroupCommitRequest> tmp = this.requestsWrite;

this.requestsWrite = this.requestsRead;

this.requestsRead = tmp;

}

swapRequests 这个方式就是在交换读集合和写集合。

最终再去处理的时候是从 requestsRead 集合当中去取。

image.png

所以从 run 方法中可以看到,doCommit 被触发了之后,就会取这个数据,如果 requestsRead 这里没有数据,就会去阻塞。

一旦有请求到来之后,它先将两个集合的数据进行一个交换,然后再让 doCommit 去处理。

synchronized (this) {

this.swapRequests();

}

image.png

如上图,首先去遍历当前集合 req 当中所有的请求对象

然后还有一个遍历 flushOK 会遍历两次,

For (int i = 0;i < 2 && !flushOK; i++){

flushOK = CommitLog.this.MappedFileQueue.getFlushedWhere() >= rep.getNextOffset();

If (!flushOK){

CommitLog.this.mappedFileQueue.flush(flushLeastPages:0);

如果文件数据存在跨文件存储,那么它要把前一个文件给它去拿到,再把后一个文件也拿到,然后这两个文件拼接起来之后才是一个完整的消息数据。这里主要考虑到消息的跨文件的问题。

然后就进行刷盘的处理

flushOK = CommitLog.this.mappedFileQueue.getFlushedWhere() >= req.getNextOffset(); //进行判断

刷完盘之后会进行一个判断,判断刷盘的位置 getFlushedWhere 如果大于当前写的位置 req.getNextOffset ,那就代表当前刷盘成功,之后正常返回。

CommitLog.this.defaultMessageStore.getStoreCheckpoint().setPhysicMsgTimestamp(storeTimestamp);

//更新刷盘存储点

最终更新到磁盘中如下图所示位置。

image.png

相关文章
|
iOS开发 UED
Flutter 动态修改应用图标功能指南
探索Flutter中动态应用图标的实现方法,了解如何为用户提供独特体验,促进用户升级和应用内购买。
554 0
Flutter 动态修改应用图标功能指南
|
Ubuntu 安全 Linux
盘点|2021年最受欢迎Linux桌面操作系统前十名
根据各操作系统镜像站后台下载量,阿里云镜像站统计了2021年最受欢迎的Linux桌面操作系统,仅根据调用量排名,供大家参考。排位最高的还是Centos,受中国Linux用户欢迎的Ubuntu、Debian均进入了前十,国内的优麒麟操作系统排在第7位。
12359 3
|
SQL 关系型数据库 MySQL
orchestrator搭建mysql高可用
orchestrator搭建mysql高可用
365 0
|
11月前
|
存储 人工智能 自然语言处理
《数据孤岛:AI模型训练之殇,精度与泛化的双重困境》
在人工智能快速发展的今天,数据是模型的“燃料”。然而,数据孤岛现象——即数据因系统、管理和流程原因被孤立存储,缺乏有效整合——正严重阻碍AI的发展。据调研,40%的企业存在50多个数据孤岛,这一问题导致AI模型训练精度和泛化能力下降,影响从医疗诊断到自动驾驶等多领域的应用效果。解决数据孤岛需要企业、科研人员及政府共同努力,通过统一数据标准、创新技术和完善政策,促进数据共享与融合,推动AI技术释放更大价值。
606 19
|
云安全 人工智能 安全
|
运维 监控 安全
云时代下的运维转型之路:从反应式到主动智能
【8月更文挑战第23天】在数字化转型的浪潮中,传统的运维模式正面临前所未有的挑战。本文将探讨如何从被动应对故障的反应式运维,转变为通过数据驱动和智能化工具实现的主动智能运维。我们将深入分析现代运维的核心要素,包括自动化、监控、数据分析和团队文化的转变,以及这些变化如何帮助企业提升运维效率,降低风险,并最终实现业务价值的最大化。文章旨在为运维专业人士提供一条清晰的转型路径,帮助他们在云时代保持竞争力。
|
前端开发 应用服务中间件 Linux
使用阿里云服务器部署前端项目
使用阿里云服务器部署前端项目,完成后可通过服务器域名访问网页
2813 0
使用阿里云服务器部署前端项目
|
Docker 容器
Docker(三):Docker镜像加速器和常用命令
Docker(三):Docker镜像加速器和常用命令
1018 0
Docker(三):Docker镜像加速器和常用命令
|
监控 安全 网络安全
网络安全威胁分析:入侵检测和安全事件响应
在当今数字化的世界中,网络安全威胁已经成为企业和组织面临的重要挑战。恶意攻击者不断寻找突破网络安全防御的漏洞,这使得入侵检测和安全事件响应变得至关重要。本文将介绍网络安全威胁分析的基本概念,以及入侵检测和安全事件响应的关键策略和工具。
757 0