領導說馬上給解決方案
其實本質針對的場景,都是說,可能你的消費端出了問題,不消費了;或者消費的速度極其慢,接著就坑爹了,可能你的訊息佇列集群的磁盤都快寫滿了,都沒人消費,這個時候怎么辦?或者是這整個就積壓了幾個小時,你這個時候怎么辦?或者是你積壓的時間太長了,導致比如 RabbitMQ 設定了訊息過期時間后就沒了怎么辦?
所以就這事兒,其實線上挺常見的,一般不出,一出就是大 case,一般常見于,舉個例子,消費端每次消費之后要寫 mysql,結果 mysql 掛了,消費端 hang 那兒了,不動了;或者是消費端出了個什么岔子,導致消費速度極其慢,
關于這個事兒,我們一個一個來梳理吧,先假設一個場景,我們現在消費端出故障了,然后大量訊息在 mq 里積壓,現在出事故了,慌了,
大量訊息在 mq 里積壓了幾個小時了還沒解決
幾千萬條資料在 MQ 里積壓了七八個小時,從下午 4 點多,積壓到了晚上 11 點多,這個是我們真實遇到過的一個場景,確實是線上故障了,這個時候要不然就是修復 consumer 的問題,讓它恢復消費速度,然后傻傻的等待幾個小時消費完畢,這個肯定不能在面試的時候說吧,
一個消費者一秒是 1000 條,一秒 3 個消費者是 3000 條,一分鐘就是 18 萬條,所以如果你積壓了幾百萬到上千萬的資料,即使消費者恢復了,也需要大概 1 小時的時間才能恢復過來,
一般這個時候,只能臨時緊急擴容了,具體操作步驟和思路如下:
先修復 consumer 的問題,確保其恢復消費速度,然后將現有 consumer 都停掉,
新建一個 topic,partition 是原來的 10 倍,臨時建立好原先 10 倍的 queue 數量,
然后寫一個臨時的分發資料的 consumer 程式,這個程式部署上去消費積壓的資料,消費之后不做耗時的處理,直接均勻輪詢寫入臨時建立好的 10 倍數量的 queue,
接著臨時征用 10 倍的機器來部署 consumer,每一批 consumer 消費一個臨時 queue 的資料,這種做法相當于是臨時將 queue 資源和 consumer 資源擴大 10 倍,以正常的 10 倍速度來消費資料,
等快速消費完積壓資料之后,得恢復原先部署的架構,重新用原先的 consumer 機器來消費訊息,
mq 中的訊息過期失效了
假設你用的是 RabbitMQ,RabbtiMQ 是可以設定過期時間的,也就是 TTL,如果訊息在 queue 中積壓超過一定的時間就會被 RabbitMQ 給清理掉,這個資料就沒了,那這就是第二個坑了,這就不是說資料會大量積壓在 mq 里,而是大量的資料會直接搞丟,
這個情況下,就不是說要增加 consumer 消費積壓的訊息,因為實際上沒啥積壓,而是丟了大量的訊息,我們可以采取一個方案,就是批量重導,這個我們之前線上也有類似的場景干過,就是大量積壓的時候,我們當時就直接丟棄資料了,然后等過了高峰期以后,比如大家一起喝咖啡熬夜到晚上12點以后,用戶都睡覺了,這個時候我們就開始寫程式,將丟失的那批資料,寫個臨時程式,一點一點的查出來,然后重新灌入 mq 里面去,把白天丟的資料給他補回來,也只能是這樣了,
假設 1 萬個訂單積壓在 mq 里面,沒有處理,其中 1000 個訂單都丟了,你只能手動寫程式把那 1000 個訂單給查出來,手動發到 mq 里去再補一次,
mq 都快寫滿了
如果訊息積壓在 mq 里,你很長時間都沒有處理掉,此時導致 mq 都快寫滿了,咋辦?這個還有別的辦法嗎?沒有,誰讓你第一個方案執行的太慢了,你臨時寫程式,接入資料來消費,消費一個丟棄一個,都不要了,快速消費掉所有的訊息,然后走第二個方案,到了晚上再補資料吧,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/254049.html
標籤:其他
上一篇:分布式介紹
