1. 程式人生 > >訊息佇列技術點梳理(思維導圖版)

訊息佇列技術點梳理(思維導圖版)

訊息佇列作為服務/應用之間的通訊中介軟體,可以起到業務耦合、廣播訊息、保證最終一致性以及錯峰流控(克服短板瓶頸)等作用。本文不打算詳細深入講解訊息佇列,而是體系化的梳理訊息佇列可能涉及的技術點,起到提綱挈領的作用,構造一個巨集觀的概念,使用思維導圖梳理。

再介紹之前,先簡短比較下RPC和訊息佇列。RPC大多屬於請求-應答模式,也包括越來越多響應式正規化,對於需要點對點互動、強事務保證和延遲敏感的服務/應用之間的通訊,RPC是優於訊息佇列的。那麼訊息佇列(下文也簡稱MQ,即Message Queueu)可以看做是一種非同步RPC,把一次RPC變為兩次,進行內容轉存,再在合適的時機投遞出去。訊息佇列中介軟體往往是一個分散式系統,內部元件間的通訊仍然會用到RPC。

目前開源界用的比較多的選型包括,ActiveMQRabbitMQKafka、阿里巴巴的Notify、MetaQ、RocketMQ。下文的技術點梳理也是學習借鑑了這些開源元件,然後萃取出一些通用技術點。

關於訊息佇列的體系化認知,見下方的思維導圖。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

1. 整體架構

一般分為producer,broker,consumer三者。

2. RPC通訊

詳細參考《體系化認識RPC》(http://www.infoq.com/cn/articles/get-to-know-rpc)。

3. 高效能保證

主要考慮MQ的延遲和吞吐。

高效能投遞方面,分為producer和broker考慮。producer可以同步變非同步、單條變批量保證傳送端高效能,批量傳送的觸發條件可以分為buffer滿或者時間視窗到了。broker可以進行多topic劃分,再多分割槽/queue來進行分治(Divide and Conquer)策略,加大並行度,分散投遞壓力。另外broker對於需要持久化的訊息,可以使用順序IO,page cache,非同步刷盤等技術提高效能,但是非同步刷盤在掉電的情況下,可能會丟失資料,可以結合下面的高可用方案,在資料嚴格不丟和高效能吞吐之間做折中。

高效能消費,即consumer和broker通訊,進行推、拉訊息。使用consumer group水平擴充套件消費能力,需要按照業務場景使用分割槽有序或者無序消費。零拷貝技術節省broker端使用者態到核心態的資料拷貝,直接從page cache傳送到網路,從而最大化傳送效能。consumer批量pull,broker批量push。broker端還可以做訊息過濾,可通過tag或者外掛實現。

4. 高可用保證

主要針對broker而言。

叢集高可用,producer通過broker投遞訊息,所以必然有且僅有一個broker主負責“寫”,選主策略分為自動選主和非主動選擇,自動選主使用分佈一致性元件完成,例如Kafka使用zookeeper,非自動選主,例如RocketMQ依賴多個無狀態的name server。

資料高可用,針對broker持久化積壓訊息場景。可藉助分散式儲存完成,但是往往效能上是個短板,所以大多數主流產品都進行本地IO順序寫,進行主從備份,多副本拷貝保證可用性,例如RocketMQ分為同步雙寫和非同步複製,前者像HDFS一樣,寫完多個副本再返回producer成功,有一定效能損失,但不大,後者最大化效能,但是當主掛的時候,資料有丟失風險。

同樣,MQ叢集也需要考慮跨機房高可用(非“異地多活”),broker的寫高可用,要考慮最小化MTTR,同時不阻塞consumer消費。

5. 擴充套件性保證

採用分治(Divide and Conquer)策略,加大投遞和消費的並行度,多個topic、多個分割槽/queue、多個副本、多個slave或者映象。

6. 協議

producer、consumer和broker通訊的協議,包括AMQP、STOMP、MQTT、HTTP、OpenWire(ActiveMQ)、XMPP、自定義等等。

AMQP是比較全面和複雜的一個協議,包括協議本身以及模型(broker、exchange、routing key等概念),目前RabbitMQ是AMQP訊息佇列最有名的開源實現,有非常多語言已經支援基於AMQP協議與訊息佇列通訊,同時還可以通過外掛支援STOMP、MQTT等協議接入。Kafka、RocketMQ均使用自定義的協議。

7. 消費關係

包括三種

1) 點對點,也就是P2P,FIFO的佇列,可以看做單播。

2) Topic模式,Pub/Sub釋出訂閱。

3) fanout廣播模式。

8. 訊息堆積能力

持久化訊息,如果儲存在本地磁碟,可以使用同步刷盤和非同步刷盤兩種策略。磁碟不能無限堆積,會有清理策略,例如Kafka、RocketMQ都按照時間、資料量進行retention。

非持久化,僅放在記憶體,消費者處理完可選擇刪除掉。

9. 可靠投遞

對於producer,從API和I/O層面可使用同步、非同步,對於吞吐層面可使用單條、批量。fire-and-forget模式,類似UDP,儘管傳送即可。針對可能發生的錯誤,例如連線broker失敗,RPC超時、釋出訊息失敗、釋出後無響應,可選擇忽略或者重發,所以往往重複投遞的情況不可避免。

對於broker,如果要保證資料100%不丟,是可能的,但是需要犧牲下效能和吞吐,使用同步多寫、多副本策略+同步刷盤持久化訊息,可以嚴格保證不丟。另外,broker對於寫入訊息的payload,也會做完整性校驗,例如CRC等。

10. 可靠消費

消費次數,包括at most once、at least once、exactly once,其中前兩個比較好做到,最後的exactly once需要streaming consumer系統和broker端協作完成,例如storm的trident和flink。

推拉模式,push or pull。推模式最小化投遞延遲,但是沒有考慮consumer的承載能力,拉一般是輪詢接收broker的資料,按照consumer自己的能力消費。

消費記錄點,一般每個訊息都有一個offset、ID或者時間戳,consumer可以按照這個offset來進行定點消費以及訊息重放。

訊息確認,consumer消費完成ACK回撥broker或者叢集高可用中介軟體(zk)通知消費進度。

錯誤處理,對於消費失敗的情況,可以回覆NACK,要求重發/requeue訊息,當錯誤超多一定閾值時候,放到死信佇列中。

訊息重複消費,這和消費次數有關係,consumer在某些時候需要做到冪等性,保證重複消費不會引起業務異常。

11. 訊息型別

順序訊息,有序的話,分為分割槽有序或者全域性有序,前者可以按照某個業務ID取模,在傳送端發到不同的分割槽/queue即可,後者往往需要單個佇列才可以滿足。無序消費則可最大化吞吐。

定時訊息,事務訊息,例如RocketMQ均支援。

12. 訊息查詢

目前RocketMQ支援訊息根據msgId查詢。

13. 生態融合

客戶端語言的豐富性,與其他系統的整合度,例如Kafka和大資料技術棧融合很緊密,Spark、Storm、Flink、Kylin都有對應的connector。

14. 管理工具

分散式系統的管理是提高生產效率的必備保障,一個好的系統,如果周邊工具不完善,對於使用者會很不友好,推廣也會有困難。

對於訊息佇列,可以從topic管理、broker管理、叢集管理、許可權/配額管理、多租戶、客戶端工具、監控、報警、控制檯Console UI來全方位進行治理。

出處:http://neoremind.com/2018/03/訊息佇列技術點梳理/

版權申明:內容來源網路,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。

640?wx_fmt=png

架構文摘

ID:ArchDigest

網際網路應用架構丨架構技術丨大型網站丨大資料丨機器學習

640?wx_fmt=jpeg

更多精彩文章,請點選下方:閱讀原文