關於MQ的幾件小事(六)訊息積壓在訊息佇列裡怎麼辦

一條路上的鹹魚發表於2019-05-22

1.大量訊息在mq裡積壓了幾個小時了還沒解決

場景: 幾千萬條資料在MQ裡積壓了七八個小時,從下午4點多,積壓到了晚上很晚,10點多,11點多。線上故障了,這個時候要不然就是修復consumer的問題,讓他恢復消費速度,然後傻傻的等待幾個小時消費完畢。這個肯定不行。一個消費者一秒是1000條,一秒3個消費者是3000條,一分鐘是18萬條,1000多萬條。 所以如果你積壓了幾百萬到上千萬的資料,即使消費者恢復了,也需要大概1小時的時間才能恢復過來。
解決方案:
這種時候只能操作臨時擴容,以更快的速度去消費資料了。具體操作步驟和思路如下:
①先修復consumer的問題,確保其恢復消費速度,然後將現有consumer都停掉。

②臨時建立好原先10倍或者20倍的queue數量(新建一個topic,partition是原來的10倍)。

③然後寫一個臨時分發訊息的consumer程式,這個程式部署上去消費積壓的訊息,消費之後不做耗時處理,直接均勻輪詢寫入臨時建好分10數量的queue裡面。

④緊接著徵用10倍的機器來部署consumer,每一批consumer消費一個臨時queue的訊息。

⑤這種做法相當於臨時將queue資源和consumer資源擴大10倍,以正常速度的10倍來消費訊息。

⑥等快速消費完了之後,恢復原來的部署架構,重新用原來的consumer機器來消費訊息。

kafka的示意圖.png

2.訊息設定了過期時間,過期就丟了怎麼辦

假設你用的是rabbitmq,rabbitmq是可以設定過期時間的,就是TTL,如果訊息在queue中積壓超過一定的時間就會被rabbitmq給清理掉,這個資料就沒了。那這就是第二個坑了。這就不是說資料會大量積壓在mq裡,而是大量的資料會直接搞丟。
解決方案:
這種情況下,實際上沒有什麼訊息擠壓,而是丟了大量的訊息。所以第一種增加consumer肯定不適用。 這種情況可以採取 “批量重導” 的方案來進行解決。 在流量低峰期(比如夜深人靜時),寫一個程式,手動去查詢丟失的那部分資料,然後將訊息重新傳送到mq裡面,把丟失的資料重新補回來。

3.積壓訊息長時間沒有處理,mq放不下了怎麼辦

如果走的方式是訊息積壓在mq裡,那麼如果你很長時間都沒處理掉,此時導致mq都快寫滿了,咋辦?這個還有別的辦法嗎?
解決方案:
這個就沒有辦法了,肯定是第一方案執行太慢,這種時候只好採用 “丟棄+批量重導” 的方式來解決了。

首先,臨時寫個程式,連線到mq裡面消費資料,收到訊息之後直接將其丟棄,快速消費掉積壓的訊息,降低MQ的壓力,然後走第二種方案,在晚上夜深人靜時去手動查詢重導丟失的這部分資料。

上一篇《如何保證訊息按順序執行

下一篇《如果讓你設計一個MQ,你怎麼設計

相關文章