RocketMQ存儲篇——MapedFileQueue

MapedFileQueue

應用層訪問commitlog和consumequeue文件是通過MappFileQueue來操作MapedFile類,從而間接操作磁盤上面的文件;MappFileQueue是由多個MapedFile隊列組成的,該類的結果如下圖所示。
這裏寫圖片描述
功能清單如下:

1. 獲取在某時間點之後更新的文件(getMapedFileByTime)

方法getMapedFileByTime(final long timestamp),遍歷MapedFile列表,若遇到文件的更新時間戳大於某時間點timestamp則返回該MapedFile對象,遍歷完之後仍然沒有找到則返回列表的最後一個MapedFile對象。

清理指定偏移量所在文件之後的文件(truncateDirtyFiles)

方法truncateDirtyFiles(long offset):遍歷MapedFile列表,每個MapedFile對象對應着一個固定大小的文件,若當文件的起始偏移量fileFromOffset<=offset<=fileFromOffset+fileSize,則表示指定的位置偏移量offset落在的該文件上,則將對應的MapedFile對象的wrotepostion和commitPosition設置爲offset%fileSize,若文件的起始偏移量fileFromOffset>offset,即是命中的文件之後的文件,則將這些文件刪除並且從MappFileQueue的MapedFile列表中清除掉。

獲取或創建最後一個文件(getLastMapedFile)

從MapedFile列表中獲取最後一個MapedFile對象,若列表爲空或者最後一個對象對應的文件已經寫滿,則創建一個新的文件(即新的MapedFile對象);若存在最後一個文件(對應最後一個MapedFile對象)並且未寫滿,則直接返回最後一個MapedFile對象。
若列表爲空,則創建的新文件的文件名(即fileFromOffset值)爲0;若最後一個文件寫滿,則新文件的文件名等於最後一個文件的fileFromOffset+fileSize;
若在Broker啓動初始化的時候會創建了後臺服務線程(AllocateMapedFileService服務),則調用AllocateMapedFileService.putRequestAndReturnMapedFile方法,在該方法中用下一個文件的文件路徑、下下一個文件的路徑、文件大小爲參數初始化AllocateRequest對象,並放入該服務線程的requestQueue:PriorityBlockingQueue<AllocateRequest>變量中,由該線程在後臺監聽requestQueue隊列,若該隊列中存在AllocateRequest對象,則利用該對象的變量值創建MapedFile對象(即在磁盤中生成了對應的物理文件),並存入AllocateRequest對象的MapedFile變量中,並且在下一個新文件之後繼續將下下一個新文件也創建了。若是在當前線程中直接創建MappeFile對象,則只創建一個新的文件。
最後將創建或返回的MapedFile對象存入MapedFileQueue的MapedFile列表中,並返回該MapedFile對象給調用者。

獲取列表中的最後一個文件(getLastMapedFile2)

從MapedFile列表中獲取最後一個MapFile對象;若列表爲空則返回null。

統計內存的數據還有多少未持久化(howMuchFallBehind)

調用getLastMapedFile方法獲取Mapped隊列中最後一個MapedFile對象,計算得出未刷盤的消息大小,計算公式爲:最後一個MapedFile對象fileFromOffset+寫入位置wrotepostion-commitedWhere(上次刷盤的位置)。

獲取MapedFile隊列中最小Offset值(getMinOffset)

先獲取MapedFile隊列中第一個MapedFile對象,再取該對象的fileFromOffset值(即文件的名字值),該值即爲最小offset值;若MapedFile列表爲空,則直接返回-1;

獲取MapedFile隊列中最大Offset值(getMaxOffset)

獲取Mapped隊列中最後一個MapedFile對象,將最後一個MapedFile對象fileFromOffset加上寫入位置wrotepostion值即爲最大offset值。

刪除某類文件中的最後一個文件(deleteLastMaped)

例如commit類型的文件下面有多個固定大小(1G)的文件,即對應在MapedFile列表中有多個MapedFile對象,若要刪除最後一個文件,首先從磁盤中刪除物理文件,然後從列表中刪除最後一個MapedFile對象。

根據指定的offset找到所在文件(findMapedFileByOffset)

方法findMapedFileByOffset(final long offset, final boolean returnFirstOnNotFound):首先找到MapedFile隊列中的第一個MapedFile對象,取該對象的fileFromOffset值;然後指定的offset減去fileFromOffset值再除以fileSize得到文件在MapedFile隊列中的序列號index,最後根據index值從列表中獲取MapedFile對象。若index值獲取對象時出錯誤(index<0或者大於列表的總數),則根據returnFirstOnNotFound參數決定是返回null或者第一個MapedFile對象。

MapedFile隊列中的消息刷盤(commit)

首先根據commitWhere值(上次刷盤的位置)在隊列中找到所處的文件對象MapedFile,即調用findMapedFileByOffset方法;然後調用MapedFile對象的commit方法完成消息刷盤操作;最後利用MapedFile對象的fileFromOffset值加上這次刷盤的消息大小得到的總和更新commitWhere值,作爲下次刷盤的開始位置,同時更新MapedFileQueue對象的存儲時間戳(storeTimestamp)。

發佈了59 篇原創文章 · 獲贊 56 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章