天天看點

rocketmq的消息存取

rocketmq是我們常用的消息中間件之一,現在我們就來分析一下,它是如何存儲和讀取消息的。

rocketmq是把消息持久化在本地的檔案系統的,所有的消息,都儲存在commitLog檔案中,這個檔案是不區分topic或者messageQueue的,所有的消息,都是儲存在一起,這個點跟常見的kafka不同,kafka不同的分區,是儲存在不同的檔案中的,但是也是以引發了别的問題,就是在分區特别多的時候,由于檔案數量太多,導緻資料的讀取效率急速下降,一般在幾十個分區左右,不建議使用過多的分區,但是rocketmq最多可以支援上萬的topic,就是因為兩者的檔案存儲不同。因為rocketmq檔案存儲使用的是同一個檔案,是以消息的寫入是順序的,每來一個消息,寫入檔案尾就可以了,效率很快。

但是光使用一個commitLog檔案,肯定是不行的,因為不同的消費者,消費的messageQueue不同(這個具體可以看rocketmq的消費模型),不能每次拉取消息時,服務端都要周遊commitLog,然後找到對應的消息傳回,這樣效率太低了,這個時候,rocketmq使用的就是ConsumeQueue檔案,該檔案可以了解為是邏輯上的隊列,一個consumeQueue檔案,對應一個服務端上的messageQueue,但是裡面存儲的不是真正的消息體,而是該MessageQueue裡面消息存儲在commitLog檔案中的的位置,是以檔案尺寸是很小的,實際情況下,大部分的consumeQueue都是能全部存入記憶體中的,也就是可以很快的知道該messageQueue中的下一條消息在commitLog的位置,再通過RandomAccessFile來實作随機讀,同樣可以達到很快的消息讀取效率。

rocketmq的消息存取

rocketmq的存儲結構如圖所示,producer發送消息到服務端之後,直接存儲在commit Log檔案中,同時根據消息的messageQueue資訊,在對應的comsumeQueue檔案的尾部,添加這條消息的記錄,也就是在commitLog檔案中的位置,不同的消費者,根據消費的MessageQueue,通過對應的ConsumeQueue擷取消息位置,并擷取消息。

總體來說,rocketmq是通過實作順序讀,随機寫,來保證自己的效率的。