1、CommitLog 文件生成規則
偏移量:每個 CommitLog 文件的大小爲 1G,一般情況下第一個 CommitLog 的起始偏移量爲 0,第二個 CommitLog 的起始偏移量爲 1073741824 (1G = 1073741824byte)。
2、怎麼知道消息存儲在哪個 CommitLog 文件上?
假設 1073742827 爲物理偏移量(物理偏移量也即全局偏移量),則其對應的相對偏移量爲 1003(1003 = 1073742827 - 1073741824),並且該偏移量位於第二個 CommitLog。
index 和 ComsumerQueue 中都有消息對應的物理偏移量,通過物理偏移量就可以計算出該消息位於哪個 CommitLog 文件上。
3、CommitLog 文件命名規則
public MappedFile getLastMappedFile(final long startOffset, boolean needCreate) {
long createOffset = -1;
MappedFile mappedFileLast = getLastMappedFile();
// 1、如果 mappedFileLast 爲空或者已滿,則計算新文件的物理偏移量
if (mappedFileLast == null) {
createOffset = startOffset - (startOffset % this.mappedFileSize);
}
if (mappedFileLast != null && mappedFileLast.isFull()) {
createOffset = mappedFileLast.getFileFromOffset() + this.mappedFileSize;
}
if (createOffset != -1 && needCreate) {
// 2、通過物理偏移量獲得文件名
String nextFilePath = this.storePath + File.separator + UtilAll.offset2FileName(createOffset);
String nextNextFilePath = this.storePath + File.separator
+ UtilAll.offset2FileName(createOffset + this.mappedFileSize);
MappedFile mappedFile = null;
if (this.allocateMappedFileService != null) {
mappedFile = this.allocateMappedFileService.putRequestAndReturnMappedFile(nextFilePath,
nextNextFilePath, this.mappedFileSize);
} else {
try {
mappedFile = new MappedFile(nextFilePath, this.mappedFileSize);
} catch (IOException e) {
log.error("create mappedFile exception", e);
}
}
// 省略代碼
......
}
新創建的 mappedFile 物理偏移量計算
- 1、如果 mappedFileLast 爲空,那麼肯定是第一次啓動 MQ,那麼物理偏移量爲0。
- 2、如果 mappedFileLast 已滿,則獲取上一個 mappedFile 的起始物理偏移量 + 文件大小。
文件名通過調用UtilAll.offset2FileName(createOffset)
進行獲取。
獲取文件名
public static String offset2FileName(final long offset) {
final NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumIntegerDigits(20);
nf.setMaximumFractionDigits(0);
nf.setGroupingUsed(false);
return nf.format(offset);
}
可以看出就是根據上一步傳入 createOffset 轉化成20位的數字字符串。不夠20位前面補零。