RocketMQ CommitLog 文件規則

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位前面補零。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章