前面已經講了訊息是怎麼傳送給broker的,那broker接收到訊息後,是怎麼處理的?
為了保證訊息不丟失,RocketMQ會把訊息進行持久化,也就是說,會把訊息寫入commitlog的日誌,這個目錄是在store下面。每個日誌大小為1G,所以commitlog會有多個磁碟檔案,每個檔名是訊息的物理偏移量。
當broker接收到訊息的時候,首先會進行一些判斷,比如只能master可以寫入,Topic的長度限制為256個字元,訊息屬性長度限制為65536個字元等。
等驗證通過後,開始進行寫資料,由於可能存在併發問題,所以每次寫的時候,都需要申請鎖。
申請到鎖後,開始往commitlog裡寫資料,如果是剛開始寫入日誌檔案的時候,此時commitlog並沒有檔案,所以就會建立一個大小為1G名字為00000000000000000000的日誌檔案。如果已經存在多個日誌檔案,那直接取最後一個日誌檔案,因為日誌檔案寫完才會建立一個新的日誌檔案,那最後一個日誌檔案就是當前需要寫入的。
拿到日誌檔案後,我們需要將訊息追加到這個檔案裡,此時需要知道當前檔案的寫指標,如果是剛建立的檔案,那寫指標就是0。
這個寫指標是不能大於檔案的大小,如果超過了,說明檔案已寫滿,那是不能往裡面寫資料的。
另外一個還需要判斷的是,當前訊息是否夠放這個檔案,也就寫指標+訊息的長度(mq還會預留其他空間),是否會超過這個檔案的大小,如果不會,就寫入這個檔案,如果會,那就會建立一個新的檔案進行寫入。
寫入後,就更新上面的寫指標,也就是說,最後的寫指標就是當前寫指標+訊息的大小。最後釋放鎖,讓其他執行緒進行寫入。
其實到了這一個步驟,訊息並沒有寫到磁碟上,還只是追加到記憶體,後續再來提刷屏的過程。