RocketMQ消息堆積問題
RocketMQ消息堆積主要分為三個層次的問題:
其一是Producer生產速率過快,什么場景呢,比如Producer故障,比如DOS攻擊,比如業務高峰(超過企業預估的,例如12306訂票,雙十一下單,這些一開始的時候都有超過預期的情況)。
其二是Broker消息堆積,比如Broker的性能瓶頸,Broker同步策略導致消息堆積等
其三是Consumer本身已經拉取消息的堆積。consumer消息拉取超過一定量之后會暫停消息拉取,一方面是消費者本身消費能力的現在,另一方面是由於消費端過多的消息容易造成GC頻繁。
一般情況下我們都可以通過限流和擴容來達到快速處理堆積的消息的目標。
消息堆積的處理策略整體上說就是生產者producer限流,RocketMQ擴容,消費者consumer擴容,具體要根據監控指標來判斷。
熟悉了消息堆積場景,我們還需要明確消息堆積的診斷,常用的工具包括producer發送速率監控,producer服務器性能監控(網絡、CPU、內存等),broker性能監控(網絡、CPU、內存,磁盤使用率,GC等),消費端消費速率,消費端consumer服務器性能監控(網絡、CPU、內存、數據庫、GC等)
MQ消息積壓
這種時候只能操作臨時擴容,以更快的速度去消費數據了。具體操作步驟和思路如下:
①先修復consumer的問題,確保其恢復消費速度,然后將現有consumer都停掉。
②臨時建立好原先10倍或者20倍的queue數量(新建一個topic,partition是原來的10倍)。
③然后寫一個臨時分發消息的consumer程序,這個程序部署上去消費積壓的消息,消費之后不做耗時處理,直接均勻輪詢寫入臨時建好分10數量的queue里面。
④緊接着征用10倍的機器來部署consumer,每一批consumer消費一個臨時queue的消息。
⑤這種做法相當於臨時將queue資源和consumer資源擴大10倍,以正常速度的10倍來消費消息。
⑥等快速消費完了之后,恢復原來的部署架構,重新用原來的consumer機器來消費消息。
知識點
Topic和Partition
Topic是一個邏輯上的概念,可以看成是一類消息的聚合。從物理上來說,一個Topic是由分散在各個服務節點上的Partition組成的,每個Topic可以有多個Producer向他發送消息,也可以有多個Consumer消費其中的消息。
如圖所示,一個Topic是由分散在多台broker上的Pratition組成的,多台Produer按照一定的算法把消息發送給各個Partition上,consumer按照一定的算法去消費不同pratition上的消息。
每一個Pratition最大允許一個consumer去消費,一個consumer可以消費多個Pratition。
對於每一個Partition而言,每一個新增的消息都會分配一個offset,他是該消息在此分區中的唯一標准。kafka通過offset來維護消息順序,對於同一個分區而言,消息是有序的。
這里需要重點說明一點的是,當消費速度小於生產速度的時候,僅增加消費者是沒有用處的,因為多個消費者在同一個分區上實際是單線程資源競爭關系(當然還有一些冒險的單隊列多消費者並行方式就是:消費者接到消息就ack成功再去處理業務邏輯,這樣你就要承受消息丟失的代價),我們需要同時增加Broker上的分區數量才能解決這一問題。