RocketMQ-创建MappedFile本地文件
了解RocketMQ的都知道,它会保存所有的消息到本地文件。这个文件就是 MappedFile,每一个文件对应一个MappedFile.默认情况下大小位1g。
在MessageStoreConfig中的mapedFileSizeCommitLog设置,当然一半情况下是通过配置文件来设置的。文件路劲也都是在这个配置类里。
文件名格式是20位的数字,在这个类里生成,类似这样的(00000001000000000000 00100000000000000000 09000000000020000000):

MappedFile由MappedFileQueue管理,下面是用来生成文件的方法:
/**
* 获取最后一个 MappedFile,若不存在或文件已满,则进行创建。
* @param startOffset
* @param needCreate
* @return
*/
public MapedFile getLastMapedFile(final long startOffset, boolean needCreate) {
// 这个offeset是所有MappedFile的全局offset
long createOffset = -1; // 创建文件开始offset。-1时,不创建
MapedFile mapedFileLast = null;
{
this.readWriteLock.readLock().lock();
if (this.mapedFiles.isEmpty()) { // 一个映射文件都不存在
createOffset = startOffset - (startOffset % this.mapedFileSize);
} else {
// 如果存在MappedFile对象,则获取最后一个List<MapedFile> mapedFiles = new ArrayList<MapedFile>()
mapedFileLast = this.mapedFiles.get(this.mapedFiles.size() - 1);
}
this.readWriteLock.readLock().unlock();
} if (mapedFileLast != null && mapedFileLast.isFull()) { // 最后一个文件已满
// 通过这里你可以知道这个offset是所有文件的offse,而不是一个mappedfile的offset
createOffset = mapedFileLast.getFileFromOffset() + this.mapedFileSize;
} // 创建文件
if (createOffset != -1 && needCreate) {
// 计算文件名。从此处我们可 以得知,MappedFile的文件命名规则:
// 00000001000000000000 00100000000000000000 09000000000020000000二十位
// fileName[n] = fileName[n - 1] + n * mappedFileSize fileName[0] = startOffset - (startOffset % this.mappedFileSize)
String nextFilePath = this.storePath + File.separator + UtilAll.offset2FileName(createOffset);
log.info("shang's log >>> create mappedFile nextFilePath:{}",nextFilePath);
String nextNextFilePath =
this.storePath + File.separator
+ UtilAll.offset2FileName(createOffset + this.mapedFileSize);
// 下一个文件的地址都算出来了,也对,就新建的时候可以直接加一个mapedfilesize来计算,就是1g。1024*1024*1024
log.info("shang's log >>> nextNextFilePath:{}",nextNextFilePath); MapedFile mapedFile = null; // 两种方式创建文件
if (this.allocateMapedFileService != null) {
mapedFile =
this.allocateMapedFileService.putRequestAndReturnMapedFile(nextFilePath,
nextNextFilePath, this.mapedFileSize);
} else {
try {
mapedFile = new MapedFile(nextFilePath, this.mapedFileSize);
} catch (IOException e) {
log.error("create mapedfile exception", e);
}
} if (mapedFile != null) {
this.readWriteLock.writeLock().lock();
if (this.mapedFiles.isEmpty()) {
mapedFile.setFirstCreateInQueue(true);
}
this.mapedFiles.add(mapedFile);
this.readWriteLock.writeLock().unlock();
} return mapedFile;
} return mapedFileLast;
}
有两种方式生成mappedfile文件,第一种可以参考这篇文章:http://www.cnblogs.com/guazi/p/6850988.html
最终都是通过标黄代码那样来生成文件的。我们来看一下,就是MappedFile的构造方法:
// 创建mappedfile文件
public MapedFile(final String fileName, final int fileSize) throws IOException {
this.fileName = fileName;
this.fileSize = fileSize;
this.file = new File(fileName);
this.fileFromOffset = Long.parseLong(this.file.getName());
boolean ok = false; ensureDirOK(this.file.getParent()); try {
// 这两个都是与文件对应的mappedfile对象属性变量
this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
// 这两个是rocketmq系统的共享静态变量,用来标示虚拟内存使用情况和文件数量
TotalMapedVitualMemory.addAndGet(fileSize);
TotalMapedFiles.incrementAndGet();
ok = true;
} catch (FileNotFoundException e) {
log.error("create file channel " + this.fileName + " Failed. ", e);
throw e;
} catch (IOException e) {
log.error("map file " + this.fileName + " Failed. ", e);
throw e;
} finally {
if (!ok && this.fileChannel != null) {
this.fileChannel.close();
}
}
}
RocketMQ-创建MappedFile本地文件的更多相关文章
- 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器
引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...
- 手工创建tomcat应用,以及实现js读取本地文件内容
手工创建tomcat应用: 1.在webapps下面新建应用目录文件夹 2.在文件夹下创建或是从其他应用中复制:META-INF,WEB-INF这两个文件夹, 其中META-INF清空里面,WEB-I ...
- 用Python删除本地目录下某一时间点之前创建的所有文件
因为工作原因,需要定期清理某个文件夹下面创建时间超过1年的所有文件,所以今天集中学习了一下Python对于本地文件及文件夹的操作.网上 这篇文章 简明扼要地整理出最常见的os方法,抄袭如下: os.l ...
- JS读取/创建本地文件及目录文件夹的方法
原文链接:http://www.cnblogs.com/ayan/archive/2013/04/22/3036072.html 注:以下操作只在IE下有效! Javascript是网页制作中离不开的 ...
- 5、创建RDD(集合、本地文件、HDFS文件)
一.创建RDD 1.创建RDD 进行Spark核心编程时,首先要做的第一件事,就是创建一个初始的RDD.该RDD中,通常就代表和包含了Spark应用程序的输入源数据.然后在创建了初始的RDD之后,才可 ...
- Spark练习之创建RDD(集合、本地文件),RDD持久化及RDD持久化策略
Spark练习之创建RDD(集合.本地文件) 一.创建RDD 二.并行化集合创建RDD 2.1 Java并行创建RDD--计算1-10的累加和 2.2 Scala并行创建RDD--计算1-10的累加和 ...
- 使用Docker Toolbox 创建Docker虚拟机的方法-注意正确使用本地文件 file:参数的路径名
使用Docker Toolbox 创建v1.12.6版的Docker虚拟机的方法, 一定要注意正确使用本地文件 file:// 参数的路径名, 之前尝试创建过多次,一直都没有成功过, 无法使用 fil ...
- github 创建网络仓库 ,使用git工具将本地文件上传/删除 --- 心得
1.前言 使用 git做项目控制版本工具,当然,使用SVN也可以,但是,git让人感觉更先进一些,与GitHub结合,用起来很方便,服务端由官网控制. 而SVN分客户端和服务端,都是个人控制,因此, ...
- github创建项目,并提交本地文件
1.如图所示,不要点选"Initialize this repository with README",不然就看不到第二幅图的提示信息了 2.根据下面提示,初始化本地文件,然后上传
随机推荐
- AC日记——「SCOI2016」美味 LiBreOJ 2016
#2016. 「SCOI2016」美味 思路: 主席树: 代码: #include <bits/stdc++.h> using namespace std; #define maxa 26 ...
- hdu 1874 畅通工程(spfa 邻接矩阵 邻接表)
题目链接 畅通工程,可以用dijkstra算法实现. 听说spfa很好用,来水一发 邻接矩阵实现: #include <stdio.h> #include <algorithm> ...
- python request post上传文件额外注意点
通用用法 但上图的字段名,类型需要根据不同接口填写,如某服务接口: 因而对应的上传代码如下: # 输出参数:请求响应报文import requestsrequest_url = 'https://XX ...
- xcoj 1103 插线板(树链刨分求最大子段和)
1103: 插线板 时间限制: 1 Sec 内存限制: 128 MB提交: 14 解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...
- BZOJ 1827 [Usaco2010 Mar]gather 奶牛大集会(树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1827 [题目大意] 给出一棵有点权和边权的树, 请确定一个点,使得每个点到这个点的距离 ...
- 【快速幂】POJ3641 - Pseudoprime numbers
输入a和p.如果p不是素数,则若满足ap = a (mod p)输出yes,不满足或者p为素数输出no.最简单的快速幂,啥也不说了. #include<iostream> #include ...
- [Luogu1119]采蘑菇
题目大意: 给你一个无向图,点i在时间t[i]之前是不存在的,有q组询问,问你时间为t时从x到y的最短路. 点的编号按出现的时间顺序给出,询问也按照时间顺序给出. 思路: Floyd. Floyd的本 ...
- Idea集成svn
Idea集成svn 既然要使用svn,首先需要下载一个 svn的客户端,到这里下载对应的安装程序:http://subversion.apache.org/packages.html#windows ...
- java乱码问题总结
在基于Java的编程中,经常会碰到汉字的处里及显示的问题,比如一大堆乱码或问号. 这是因为JAVA中默认的编码方式是UNICODE,而中国人通常使用的文件和DB都是基于GB2312或者BIG5等编码, ...
- Activit(活动)实践--知晓当前活动
实际上,我们可能用的不是自己写的项目,而是从别人那里接手过来的代码,因为你刚进公司就有一个新项目开始的概率十分低.阅读别人代码时会有一个很头疼的问题,就是当你需要在某个界面上修改一些非常简单的东西时, ...