RocketMQ源码解析——存储部分(2)对`MappedFile`进一步封装的`MappedFileQueue`

MappedFileQueue

 前面已经介绍了RocketMQ跟存储交互的底层封装对象mappedFile。而跟CommitLog,ConsumeQueue进行交互的并不是mappedFile,而是对其进一步封装的MappedFileQueue类。
在这里插入图片描述

属性介绍
	//文件的存储路径
    private final String storePath;

	//映射文件大小,指的是单个文件的大小,比如CommitLog大小为1G
    private final int mappedFileSize;

	//并发线程安全队列存储映射文件
    private final CopyOnWriteArrayList<MappedFile> mappedFiles = new CopyOnWriteArrayList<MappedFile>();

    private final AllocateMappedFileService allocateMappedFileService;

	//刷新完的位置
    private long flushedWhere = 0;

	//提交完成的位置
    private long committedWhere = 0;

	//存储时间
    private volatile long storeTimestamp = 0;

MappedFileQueue这个类的属性相对来说比较少,其中需要说的是,AllocateMappedFileService类型的字段,这个对象的作用是根据情况来决定是否需要提前创建好MappedFile对象供后续的直接使用。而这个参数是在构造MappedFileQueue对象的时候的一个参数。只有在CommitLog中构造时才会传入AllocateMappedFileService,在ConsumeQueue并没有传入。

方法介绍
构造方法

MappedFileQueue只有一个全参构造器,分别是传入文件的存储路径storePath,单个存储文件的大小mappedFileSize和提前创建MappedFile对象的allocateMappedFileService

public MappedFileQueue(final String storePath, int mappedFileSize,
        AllocateMappedFileService allocateMappedFileService) {
   
        //指定文件的存储路径
        this.storePath = storePath;
        //指定单个文件的大小
        this.mappedFileSize = mappedFileSize;
        this.allocateMappedFileService = allocateMappedFileService;
    }
检查文件是否完整checkSelf
   /**
     * 检查文件的是否完整,检查的方式。上一个文件的起始偏移量减去当前文件的起始偏移量,如果差值=mappedFileSize那么说明文件是完整的,否则有损坏
     */
    public void checkSelf() {
   
        //检查文件组是否为空
        if (!this.mappedFiles.isEmpty()) {
   
            //对文件进行迭代,一个一个进行检查
            Iterator<MappedFile> iterator = mappedFiles.iterator();
            MappedFile pre = null;
            while (iterator.hasNext()) {
   
                MappedFile cur = iterator.next();

                if (pre != null) {
   
                    //用当前文件的其实偏移量-上一个文件的其实偏移量 正常情况下应该等于一个文件的大小。如果不相等,说明文件存在问题
                    if (cur.getFileFromOffset() - pre.getFileFromOffset() != this.mappedFileSize) {
   
                        LOG_ERROR.error("[BUG]The mappedFile queue's data is damaged, the adjacent mappedFile's offset don't match. pre file {}, cur file {}",
                            pre.getFileName(), cur.getFileName());
                    }
                }
                pre = cur;
            }
        }
    }

 这里检查文件是否被破坏的原理,就是检查文件的大小是不是等于前一个文件的起始偏移量和后一个文件的起始偏移量是不是等于文件大小。而这里的起始偏移量又是在MappedFile进行获取的fileFromOffset,而这个值就是我们在构造MappedFile的时候传入的文件名转化得到的

private void init(final String fileName, final int fileSize) throws IOException {
   
		//根据文件的名称计算文件其实的偏移量
        this.fileFromOffset = Long.parseLong(this.file.getName());
}
加载文件load
   public boolean load() {
   
        /**
         *System.getProperty("user.home") + File.separator + "store" + File.separator + 文件名
         * 根据传入的文件保存路径storePath 来获取文件
         */
        File dir = new File(this.storePath);
        File[] files = dir.listFiles();
        //文件列表不为空则进行加载
        if (files != null) {
   
            // ascending order
            //对文件进行排序
            Arrays.sort(files);
            for (File file : files) {
   

                //队列映射文件的大小不等于设置的文件类型的大小,说明加载到了最后的一个文件  比如 如果是commitLog那么对于的大小应该为1G
                if (file.length(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值