6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。

1.ConsumeQueueStore

java 复制代码
public class ConsumeQueueStore {

	protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;
	
	public boolean load() {
	    String storePathRootDir = this.messageStoreConfig.getStorePathRootDir();
	    String storePathConsumeQueue = getStorePathConsumeQueue(storePathRootDir);
	    boolean cqLoadResult = loadConsumeQueues(storePathConsumeQueue, CQType.SimpleCQ);
	    String storePathBatchConsumeQueue = getStorePathBatchConsumeQueue(storePathRootDir);
	    boolean bcqLoadResult = loadConsumeQueues(storePathBatchConsumeQueue, CQType.BatchCQ);
	    return cqLoadResult && bcqLoadResult;
	}
	
	//Broker启动后加载本地的consumequeue文件
	private boolean loadConsumeQueues(String storePath, CQType cqType) {
        File dirLogic = new File(storePath);
        File[] fileTopicList = dirLogic.listFiles();
        if (fileTopicList != null) {
            for (File fileTopic : fileTopicList) {
                String topic = fileTopic.getName();
                File[] fileQueueIdList = fileTopic.listFiles();
                if (fileQueueIdList != null) {
                    for (File fileQueueId : fileQueueIdList) {
                        int queueId = Integer.parseInt(fileQueueId.getName());;
                        queueTypeShouldBe(topic, cqType);
                        //选择 ConsumeQueue or BatchConsumeQueue 本文以 ConsumeQueue 作为分析案例
                        ConsumeQueueInterface logic = createConsumeQueueByType(cqType, topic, queueId, storePath);
                        this.putConsumeQueue(topic, queueId, logic);
                        if (!this.load(logic)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
	
	private void putConsumeQueue(final String topic, final int queueId, final ConsumeQueueInterface consumeQueue) {
        ConcurrentMap<Integer/* queueId */, ConsumeQueueInterface> map = this.consumeQueueTable.get(topic);
        if (null == map) {
            map = new ConcurrentHashMap<>();
            map.put(queueId, consumeQueue);
            this.consumeQueueTable.put(topic, map);
        } else {
            map.put(queueId, consumeQueue);
        }
    }
	
	public boolean load(ConsumeQueueInterface consumeQueue) {
		// 通过 topic & queueId 从consumeQueueTable 获取到 对应的FileQueueLifeCycle 即ConsumeQueue
        FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
        return fileQueueLifeCycle.load();
    }
}

1.1.ConsumeQueue

java 复制代码
public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
	
	private final MappedFileQueue mappedFileQueue;
	
	@Override
	public boolean load() {
	    boolean result = this.mappedFileQueue.load();
	    return result;
	}
}

1.2.MappedFileQueue

mappedFileQueue.load核心功能就是加载consumequeue/topic/queueId目录下的消费索引本地文件。区别CommitLog加载的是/commitlog目录下真正的用户数据。

ConsumeQueue & CommitLog 均持有属性类MappedFileQueue【mmap零拷贝之内存映射的磁盘文件】。

相关推荐
重生之我是Java开发战士1 分钟前
【Redis】Java & JavaSpring 客户端
java·redis·bootstrap
郭小李24 分钟前
mybatis的 Mapper.xml语法
xml·java·mybatis
小蒜学长27 分钟前
基于SpringBoot 框架的自媒体新闻系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·mysql数据库·自媒体新闻管理系统
96245628 分钟前
补打一条卡,为什么要从前一天重新算:人工补录与实时重算业务复盘
java·mysql·kafka
Java后端的Ai之路37 分钟前
01、Java并发编程:学习攻略如何才能学好并发编程?
java·开发语言·学习
ScilogyHunter1 小时前
Hercules系列安全MCU功能安全原理详解
java·单片机·安全·hercules
博风1 小时前
eclipse中配置maven,以及在本地使用maven。
java·eclipse·maven
云-缩影1 小时前
实际项目中怎么选排序算法:从面试题到工程落地
java·算法·排序算法
追星星の人1 小时前
java web项目(eclipse软件)全流程备份
java·servlet
文丑颜不良啊2 小时前
LeetCode1461~1480题目解析
java·leetcode