消息读写与存储结构
在rocketMQ中, 消息存储在硬盘中, commitLog与consumeQueue在结构概念上是一个队列, 但是在具体实现上是用多文件存储结构
commitLog的文件默认大小为1G, consumeQueue的文件默认大小为600w字节, 即可以存放30w个条目
public int getMappedFileSizeConsumeQueue() {
// mappedFileSizeConsumeQueue = 300000 * ConsumeQueue.CQ_STORE_UNIT_SIZE
// ConsumeQueue.CQ_STORE_UNIT_SIZE = 20
int factor = (int) Math.ceil(this.mappedFileSizeConsumeQueue / (ConsumeQueue.CQ_STORE_UNIT_SIZE * 1.0));
return (int) (factor * ConsumeQueue.CQ_STORE_UNIT_SIZE);
}
commitLog
首先看看commitLog的文件存储结构
在CommitLog类中有一个load方法, 在该方法中加载了mappedFileQueue, 即rocketMQ的逻辑队列
public boolean load() {
boolean result = this.mappedFileQueue.load();
log.info("load commit log " + (result ? "OK" : "Failed"));
return result;
}
在mappedFileQueue的load方法中:
- 读取根目录文件夹
- 遍历文件排序
- 用MappedFile类读取文件夹下的文件并且创建fileChannel
private String storePathCommitLog = System.getProperty("user.home") + File.separator + "store"
+ File.separator + "commitlog";
// CommitLog file size,default is 1G
private int mappedFileSizeCommitLog = 1024 * 1024 * 1024;
mappedFile对象就是commitLog对硬盘的操作对象
在消费流程中, 消费中订阅topic从topic下的消费队列中获取offset, 然后根据offset从commitLog中获取消息
public SelectMappedBufferResult getData(final long offset, final boolean returnFirstOnNotFound) {
// 这里的大小是默认配置的1g
int mappedFileSize = this.defaultMessageStore.getMessageStoreConfig().getMappedFileSizeCommitLog(