訊息佇列MQ應用場景及主流框架對比

pythontab發表於2019-05-08

1.什麼是MQ,有什麼用?

MQ 是message queue ,訊息佇列,也叫訊息中介軟體。訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用解耦,非同步訊息,流量削鋒等問題,實現高效能,高可用,可伸縮和最終一致性架構。目前使用較多的訊息佇列有ActiveMQ,RabbitMQ,Kafka,RocketMQ

2. 應用場景

訊息佇列 MQ 可應用於如下幾個場景:

分散式事務

在傳統的事務處理中,多個系統之間的互動耦合到一個事務中,響應時間長,影響系統可用性。引入分散式事務訊息,交易系統和訊息佇列之間,組成一個事務處理,能保證分散式系統之間資料的最終一致。;下游業務系統(購物車、積分、其他)相互隔離,並行處理。

實時計算

透過訊息佇列(MQ),將源端不停產生的資料實時流入到計算引擎,實現實時計算。可採用如下計算引擎:Spark / Storm / EMR / ARMS / BeamRunner。

物聯網應用

物聯網裝置透過微訊息佇列(LMQ)連線雲端,雙向通訊,資料傳輸;裝置資料透過訊息佇列(MQ)連線計算引擎,分析資料或者源資料實時高效寫入到 HiTSDB / HiStore / ODPS 等。

大規模快取同步

在商業大促活動中,如“雙11”大促,各個分會場會有琳琅滿目的商品,每件商品的價格都會實時變化;同時,大量併發訪問商品資料庫,會場頁面響應時間長。集中式快取,頻寬成瓶頸,無法滿足對商品價格的訪問需求。

訊息佇列(MQ)能夠透過大規模快取同步,減少頁面響應時間;針對分會場的多快取設計,滿足客戶對商品價格的訪問需求。

3. 優缺點

  1. 優勢,主要有3方面:

  • 解耦:如果A服務的一個介面需要呼叫B、C、D、E…..系統的對應介面,將資料推送給其它系統,如果採用介面呼叫,這需要在A的介面中同步(或非同步執行緒)呼叫其它系統介面。
    如果後續其中某一個系統不需要這個資料了,則需要修改A服務的介面;而且A服務需要考慮如果資料沒有推送到其它系統或個別系統的介面呼叫超時等情況,需要採取什麼措施進行彌補,系統之間耦合性很高。採用MQ,A服務只需要將資料成功推送給MQ後,就不用關心誰去消費它,降低系統之間的耦合性。

  • 非同步:場景同上,假設A本身介面呼叫時間50ms,B、C、D、E…介面呼叫時間為200ms、240ms、200ms、100ms….那麼A介面呼叫響應時間至少為790ms,響應時間要比本介面響應時間高很多,如果這些介面本身不需要同步呼叫,即A服務不需要關心其它系統的介面呼叫結果,此時將資料成功推送到MQ之後,A服務該介面就可以直接返回,可以降低系統介面的響應時間,提高系統的響應能力。

  • 削峰:假設A服務某介面平時每秒併發為500,系統承受最大併發為1000,但是在特定時間,系統的每秒併發在2000,系統承受不了這麼多的併發,很容易造成系統癱瘓。如果採用MQ進行請求排隊,設定系統每秒處理訊息數,可以降低系統癱瘓的可能性。

  • 劣勢,主要有3方面:

    • 系統可用性降低:原來系統只有A、B、C、D、E….系統,只需要保證他們的可用性就行了,但是現在引入了MQ後,又需要確保MQ的高可用,否則系統就不能正常提供服務。

    • 系統複雜性提高:原來的系統之間直接進行介面呼叫就行了,現在引入了MQ之後,需要學習使用MQ的API,還需要額外部署MQ例項,還要考慮MQ的高可用、如何防止訊息的重複消費、如何保證訊息的正確投遞和保證消費以及訊息傳遞的順序性……

    • 一致性問題:以前A服務直接呼叫其它系統的介面,可以拿到同步結果,知道其它系統的處理結果,此時整體系統的資料是一致的。引入MQ之後,A服務成功推送資料到MQ,但是不知道其它系統是否處理了、即使處理了但是也不知道是否成功,如果沒有處理或者沒有處理成功,那此時的資料和沒有引入MQ之前的資料出現了不一致。

    4.現在主流的MQ之間區別

    特性ActiveMQRabbitMQRocketMQKafka
    單機吞吐量萬級萬級10萬級,RocketMQ也是可以支撐高吞吐的一種MQ10萬級別,這是kafka最大的優點,就是吞吐量高。
    topic數量對吞吐量的影響

    topic可以達到幾百,幾千個的級別,吞吐量會有較小幅度的下降;這是RocketMQ的一大優勢,在同等機器下,可以支撐大量的topictopic從幾十個到幾百個的時候,吞吐量會大幅度下降;所以在同等機器下,kafka儘量保證topic數量不要過多。如果要支撐大規模topic,需要增加更多的機器資源
    時效性ms級微秒級,這是rabbitmq的一大特點,延遲是最低的ms級延遲在ms級以內
    可用性高,基於主從架構實現高可用性高,基於主從架構實現高可用性非常高,分散式架構非常高,kafka是分散式的,一個資料多個副本,少數機器當機,不會丟失資料,不會導致不可用
    訊息可靠性有較低的機率丟失資料
    經過引數最佳化配置,可以做到0丟失經過引數最佳化配置,可以做到0丟失
    功能支援MQ領域的功能極其完基於erlang開發,所以併發能力很強,效能極其好,延時很低,功能較為完善MQ功能較為完善,還是分散式的,擴充套件性好早期版本功能較為簡單,主要支援簡單的MQ功能,在大資料領域的實時計算以及日誌採集被大規模使用,是事實上的標準
    優劣勢總結非常成熟,功能強大,在業內大量的公司以及專案中都有應用;偶爾會有較低機率丟失訊息;而且現在社群以及國內應用都越來越少,官方社群現在對ActiveMQ 5.x維護越來越少,幾個月才釋出一個版本;而且確實主要是基於解耦和非同步來用的,較少在大規模吞吐的場景中使用erlang語言開發,效能極其好,延時很低;吞吐量到萬級,MQ功能比較完備;而且開源提供的管理介面非常棒,用起來很好用;社群相對比較活躍,幾乎每個月都發布幾個版本分;在國內一些網際網路公司近幾年用rabbitmq也比較多一些;但是問題也是顯而易見的,RabbitMQ確實吞吐量會低一些,這是因為他做的實現機制比較重。而且erlang開發,國內有幾個公司有實力做erlang原始碼級別的研究和定製?如果說你沒這個實力的話,確實偶爾會有一些問題,你很難去看懂原始碼,你公司對這個東西的掌控很弱,基本職能依賴於開源社群的快速維護和修復bug。而且rabbitmq叢集動態擴充套件會很麻煩,不過這個我覺得還好。其實主要是erlang語言本身帶來的問題。很難讀原始碼,很難定製和掌控。介面簡單易用,而且畢竟在阿里大規模應用過,有阿里品牌保障;日處理訊息上百億之多,可以做到大規模吞吐,效能也非常好,分散式擴充套件也很方便,社群維護還可以,可靠性和可用性都是ok的,還可以支撐大規模的topic數量,支援複雜MQ業務場景;而且一個很大的優勢在於,阿里出品都是java系的,我們可以自己閱讀原始碼,定製自己公司的MQ,可以掌控;社群活躍度相對較為一般,不過也還可以,文件相對來說簡單一些,然後介面這塊不是按照標準JMS規範走的有些系統要遷移需要修改大量程式碼;還有就是阿里出臺的技術,你得做好這個技術萬一被拋棄,社群黃掉的風險,那如果你們公司有技術實力我覺得用RocketMQ挺好的kafka的特點其實很明顯,就是僅僅提供較少的核心功能,但是提供超高的吞吐量,ms級的延遲,極高的可用性以及可靠性,而且分散式可以任意擴充套件;同時kafka最好是支撐較少的topic數量即可,保證其超高吞吐量;而且kafka唯一的一點劣勢是有可能訊息重複消費,那麼對資料準確性會造成極其輕微的影響,在大資料領域中以及日誌採集中,這點輕微影響可以忽略;這個特性天然適合大資料實時計算以及日誌收集

    5. 總結

      一般的業務系統在選擇MQ的時候,早期選用的大多數都是ActiveMQ,但是其社群不夠活躍,隨之大家開始使用RabbitMQ,雖然RabbitMQ是開源的,社群活躍度也高,但是因為採用erlang語言開發,對於java工程師深入研究還是帶來了不小的阻礙。最近這幾年國內的公司大多數都開始嘗試使用RocketMQ,據瞭解阿里雙11內部的訊息佇列就是基於RocketMQ最佳化的,經歷過大規模併發測試。而kafka基本都是用於大資料領域的實時計算、日誌採集等場景。
      所以小公司,技術研究能力較為一般的,採用RabbitMQ也是不錯的選擇,社群支援和文件都不錯,國內也有不少大規模使用的案例;而對於中大型公司,架構人員以及研發人員都有著不弱實力,嘗試使用RocketMQ是更好的選擇。針對於大資料等場景,基本不用考慮,直接採用Kakfa。


    相關文章