消息隊列技術點梳理(思惟導圖版)

image
做者:neoremind
出處:http://neoremind.com/2018/03/...網絡

消息隊列做爲服務/應用之間的通訊中間件,能夠起到業務耦合、廣播消息、保證最終一致性以及錯峯流控(克服短板瓶頸)等做用。本文不打算詳細深刻講解消息隊列,而是體系化的梳理消息隊列可能涉及的技術點,起到提綱挈領的做用,構造一個宏觀的概念,使用思惟導圖梳理。架構

再介紹以前,先簡短比較下RPC和消息隊列。RPC大多屬於請求-應答模式,也包括愈來愈多響應式範式,對於須要點對點交互、強事務保證和延遲敏感的服務/應用之間的通訊,RPC是優於消息隊列的。那麼消息隊列(下文也簡稱MQ,即Message Queueu)能夠看作是一種異步RPC,把一次RPC變爲兩次,進行內容轉存,再在合適的時機投遞出去。消息隊列中間件每每是一個分佈式系統,內部組件間的通訊仍然會用到RPC。異步

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

關於消息隊列的體系化認知,見下方的思惟導圖。ide

image

1. 總體架構

通常分爲producer,broker,consumer三者。工具

2. RPC通訊

詳細參考《體系化認識RPC》(http://www.infoq.com/cn/artic...)。性能

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或者插件實現。spa

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來全方位進行治理。

image

相關文章
相關標籤/搜索