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零拷贝之内存映射的磁盘文件】。

相关推荐
朦胧之7 小时前
AI 编程-老项目改造篇
java·前端·后端
程序猿大帅11 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪12 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly12 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨13 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜13 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端
SimonKing19 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户2986985301420 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波1 天前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java