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 {
            this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
            this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
            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();
            }
        }
    }
时间: 2024-11-08 17:25:00

RocketMQ-创建MappedFile本地文件的相关文章

利用git上传本地文件、文件夹到Github

 利用git上传文件至github是特别常用的,总结以下内容供参考使用. 第一步:下载git工具,[这里是链接](https://git-scm.com/downloads),选择适合自己的版本进行安装. 第二步:安装完成后,找到Git bash,双击打开. 第三步:输入自己的用户名和邮箱(为注册GITHUB账号时的用户名和邮箱) $ git config --global user.name "[email protected]" $ git config --global user

02、创建RDD(集合、本地文件、HDFS文件)

Spark Core提供了三种创建RDD的方式,包括:使用程序中的集合创建RDD:使用本地文件创建RDD:使用HDFS文件创建RDD. 1.并行化集合 如果要通过并行化集合来创建RDD,需要针对程序中的集合,调用SparkContext的parallelize()方法.Spark会将集合中的数据拷贝到集群上去,形成一个分布式的数据集合,也就是一个RDD.相当于是,集合中的部分数据会到一个节点上,而另一部分数据会到其他节点上.然后就可以用并行的方式来操作这个分布式数据集合,即RDD. // 案例:

Java本地文件操作(一)文件的创建、删除、重命名

package com.yeqc.testDemo; import java.io.File; public class HelloFile { public static void main(String[] args) { File file = new File("hello.txt"); if (file.exists()) { System.out.println(file.isFile()); System.out.println(file.isDirectory());

json解析 本地文件和网上文件(通过接口)

json解析 对本地文件解析 NSString *path =[[NSBundle mainBundle] pathForResource:@"movielist" ofType:@"txt"]; // 第二个参数,制定一个容器来接收解析后的数据 NSMutableDictionary *dic =[NSJSONSerialization JSONObjectWithData:data option:NSJSONReadingMutableContainers er

字符串,字典,数组写入本地文件和从本地文件读取

参考:http://blog.csdn.net/hakusan/article/details/39429393?utm_source=tuicool&utm_medium=referral 一.字符串,字典,数组存储到本地文件 字符串,数组,字典存储到本地文件过程一样,只是要存储的数据类型不同而已,这里以字符串存储到本地文件为例,如下:    NSString *content = @"将字符串存储到本地文件";    (1)获取Documents文件夹路径 参数:(1)指定

HTML5 本地文件操作之FileSystemAPI实例(二)

文件操作实例整理二 1.删除文件.复制文件.移动文件 //获取请求权限 window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(window.TEMPORARY, 5 * 1024, initFs, errorHandler); function initFs(fs) { //删除文件 fileEntry.remove() fs.

渗透测试技术之本地文件包含

概述 通过加强对本地文件包含(LFI)渗透测试技术的研究,可以帮助渗透测试人员和学生在未来的渗透测试过程中,识别和测试LFI漏洞.在Web程序渗透测试中,利用本文中的技术发现的LFI漏洞是渗透测试中的典型漏洞.此外,在本文中提到有一些技术,在CTF大赛中也经常被利用. 什么是本地文件包含(LFI)漏洞? LFI允许攻击者通过浏览器包含一个服务器上的文件.当一个WEB应用程序在没有正确过滤输入数据的情况下,就有可能存在这个漏洞,该漏洞允许攻击者操纵输入数据.注入路径遍历字符.包含web服务器的其他

HTML5 本地文件操作之FileSystemAPI实例(三)

文件夹操作demo 1.读取根目录文件夹内容 window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(window.PERSISTENT, 5 * 1024, initFs, errorHandler); function initFs(fs) { //显示根目录下的内容 var dirReader = fs.root.creat

HTML5 本地文件操作之FileSystemAPI实例(四)

目录操作Demo二 1.删除目录 window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(window.PERSISTENT, 5 * 1024, initFs, errorHandler); function initFs(fs) { //删除目录,子目录创建需要递归,获取可以直接指定'/' //如果子目录不存在,抛出删除异常