天天看點

淺談專有雲MQ存儲空間的清理機制

淺談專有雲MQ存儲空間的清理機制

在近⼀年的項⽬保障過程中,對專有雲MQ産品的存儲⽔位清理模式⼀直存疑,總想一探究竟但又苦于工作繁忙、精力有限,直到最近⼀次項⽬保障過程中再次出現了類似的問題,⼤家對MQ Broker的⽔位清理機制仍然⽐較模糊,于是便有了這篇⽂章。希望能通過這篇⽂章将MQ Broker的消息清理機制講清楚。

⾸先,我們先來看⼀張MQ的消息儲存時間和Broker磁盤存儲空間的⽔位趨勢圖(該圖來源于銅雀,⽬前已更名為SRE技術保障平台)。通過該趨勢圖,可以看到紅線左側的消息儲存時間(上⽅藍⾊趨勢線)和Broker磁盤存儲空間(下⽅綠⾊區域)呈現出規律性的波動。⽽紅線右側部分,随着消息量的快速增加(通過Broker磁盤存儲空間快速上漲得出),開始⼀段時間消息儲存時間還呈規律性波動,但接近最右側時,可以看到消息儲存時間的波動頻率加快了,⽽且消息儲存時間快速下降。那麼MQ對消息的清理機制到底是什麼呢?

淺談專有雲MQ存儲空間的清理機制

圖1:消息儲存時間&磁盤空間占比趨勢圖

在介紹清理機制前,先來複習⼀下MQ的消息是如何進⾏存儲的。

淺談專有雲MQ存儲空間的清理機制

圖2:commitlog

Producer發送的所有消息都存放在Broker節點的 /home/admin/store/commitlog ⽬錄下(專有雲場景),每個commitlog的⼤⼩固定為1G。随着時間的推移,當Broker接收的消息量越來越多時,就會在該⽬錄下⽣成多個⼤⼩為1G的commitlog⽂件。

ps: 特别聲明,雖然該⽬錄叫commitlog,但⽬錄中存儲的⽂件并不是程式⽇志,⽽是MQ Broker⽤來存儲消息的⽂件載體,在MQ産品中這種⽂件載體叫做commitlog。之是以這⾥做特别說明,是因為曆史上出現過由于誤認為此⽬錄下存儲的是程式⽇志,為了釋放磁盤存儲空間将⽬錄下的commitlog删除導緻MQ消息丢失的故障。這是⾎的教訓!這個⽬錄下的⽂件不要碰,不要碰,不要碰。

commitlog⽬錄下的⽂件讓MQ⾃行維護清理便可。那MQ⾃身是根據什麼規則來進⾏清理的呢?先來看⼀下MQ⾥⾯⼏個⽐較關鍵的門檻值:

  • 72⼩時,MQ預設的消息儲存時間。從圖1可以看出每次消息儲存時間波動下降時,均會逼近到該值。
  • 淩晨4點,MQ預設的消息清理觸發時間。從圖1可以看出每次消息儲存時間下降均在淩晨4點發生。
  • 75%,MQ預設的開始觸發清理磁盤存儲空間的門檻值。
  • 85%,MQ内置的開始強制清理磁盤存儲空間的門檻值。
  • 90%,MQ内置的Broker開始禁寫的磁盤存儲空間的門檻值。

MQ會在兩個時機對commitlog進⾏清理,⼀是前文提到的每天淩晨4點;另⼀個是消息寫⼊時。通過以下表格可以更加清楚的看出具體的清理政策。

淺談專有雲MQ存儲空間的清理機制

清理模式

  • 普通清理,這種清理模式隻将72⼩時之前的commitlog清理掉,MQ在保證存儲72⼩時消息的前提下,盡量降低磁盤空間使⽤率。
  • 強制清理,這種清理模式隻在Broker存儲空間⾼于85%的情況下觸發,此時MQ在對commitlog進⾏清理時,将不再考慮72⼩時的消息保留時間,⽽是要盡可能保證能夠接收新的MQ消息進來,是以會強制對 commitlog進⾏清理(因為如果不清理,磁盤空間使⽤率進⼀步上漲到90%後,Broker便會⾃動禁寫,新的消息便⽆法寫入)。當然也不會⼀次性将所有的commitlog清理掉,⽽是隻批量清理⼀部分(代碼中設定⼀個broker⼀次最多清理10個commitlog⽂件)。

我們回過頭來再看⼀下這個趨勢圖。

淺談專有雲MQ存儲空間的清理機制

圖3:消息儲存時間&磁盤空間占比趨勢圖

  • 圖中1,2,3,4,5,6 處,Broker的存儲空間均未超過75%,在每⽇淩晨4點觸發了定時清理,将72⼩時之前的消息清理掉。可以看到在清理完成後,消息的儲存時間都回落到了72⼩時左右。
  • 圖中7處,Broker的存儲空間使⽤率第⼀次達到了75%,但低于85%,觸發了消息寫⼊時的普通清理,此時清理的還是72⼩時之前的消息,可以看到消息儲存時間在清理完成後回落到72⼩時左右,但存儲空間使⽤率下降的⾮常⼩,說明⽬前Broker中存儲的消息⼤部分都是72⼩時以内産⽣的。
  • 圖中8處,随着消息的發送(消息寫⼊速度⽐較快),存儲空間使⽤率第⼆次達到了75%,仍低于85%,此時普通清理仍然是清理72⼩時之前的消息資料,可以看到磁盤空間使⽤率并沒有明顯下降。說明此時消息的寫⼊速度已經⾼于commitlog的清理速度。
  • 8之後發⽣的事情,由于此時消息寫⼊速度⾼于commitlog清理速度,雖然消息寫⼊時會觸發清理動作,但此時Broker中的消息都是72⼩時以内發送的,沒有清理掉任何commitlog,磁盤⽔位并沒有降低。随着消息的不斷寫⼊,Broker的存儲⽔位不斷升⾼,消息的儲存時間基本維持不變。
  • 8之後的之後,當Broker的存儲⽔位達到85%,此時Broker為了後續還能繼續提供服務,會開啟強制清理,此時MQ不再考慮72⼩時的消息保留時間,⽽是優先保證後續消息的順利寫⼊,于是會将72⼩時以内的消息也進⾏清理。整體表現為Broker的存儲⽔位達到85%時,基本不會上漲(隻有在消息寫⼊量特别⼤時,消息寫⼊速度遠遠⼤于commitlog清理速度,才會繼續上漲),但由于清理了72⼩時以内的消息,會使Broker的消息儲存時間開始降低,開始低于72⼩時,并随着後續清理動作不斷降低。

    如上所述,消息寫⼊量特别⼤,消息寫⼊速度遠⾼于commitlog的清理速度,Broker的存儲⽔位在達到85%後還會繼續升⾼,直至達到90%時,Broker為了保護⾃身服務可⽤性,會⾃動開啟禁寫,此時發送到該Broker的消息會被拒絕掉。Broker的存儲⽔位不會進⼀步上升,⽽且此時Broker會開啟強制清理,對72⼩時以内的消息進⾏清理,以便使Broker的存儲⽔位降到90%以下,使Broker可以重新對外提供服務。

ps:實際在MQ的代碼實作層⾯,為了保證消息寫⼊Broker的性能,并不是每次寫⼊消息時都進⾏存儲

空間檢查和commitlog清理,⽽是通過定時任務來執⾏(該定時任務每10s執⾏⼀次)。

上述介紹的⼏個清理門檻值中,有些是可調的,有些是内置在代碼中不可調的。⽐如“淩晨4點”,“72⼩時”,“75%”,這3個參數是⽤戶可以調整的MQ配置,“85%”,“90%”是寫死在代碼中的,是⽆法調整的。

檢視Broker配置資訊的⽅式如下,在Broker的docker中執⾏:

sh /home/admin/rmq/bin/mqadmin getBrokerConfig -b ${IP}:10911           
  • deleteWhen,對應“淩晨4點”
  • fileReservedTime,對應“72⼩時”
  • diskMaxUsedSpaceRatio,對應“75%”

在調整配置時,deleteWhen通常選在客戶MQ業務的低峰期進⾏,盡量避免commitlog清理對⽣産業務的影響。當Broker存儲⽔位出現快速上漲時,為避免存儲⽔位達到90%,出現禁寫影響⽣産業務的情況,需要同時調整fileReservedTime和diskMaxUsedSpaceRatio的預設設定,通過調整這兩個參數共同作⽤保證Broker的存儲空間可以及時得到清理(還有⼀種降⽔位的⽅式——關閉MQ消息軌迹)。當然這所有參數的調整都需要經過與産研的溝通與确認。

以上就是對MQ Broker消息清理機制的剖析,希望通過這篇⽂章能夠讓大家了解并掌握其清理機制,能夠處理實際工作中遇到的MQ Broker存儲⽔位快速上漲的問題。

我們是阿裡雲智能全球技術服務-SRE團隊,我們緻力成為一個以技術為基礎、面向服務、保障業務系統高可用的工程師團隊;提供專業、體系化的SRE服務,幫助廣大客戶更好地使用雲、基于雲建構更加穩定可靠的業務系統,提升業務穩定性。我們期望能夠分享更多幫助企業客戶上雲、用好雲,讓客戶雲上業務運作更加穩定可靠的技術,您可用釘釘掃描下方二維碼,加入阿裡雲SRE技術學院釘釘圈子,和更多雲上人交流關于雲平台的那些事。

淺談專有雲MQ存儲空間的清理機制