做者:愛釣魚的桌子哥,資深架構師面試
1.有Broker的暴力路由:Kafka 數據庫
2.有Broker的複雜路由:RabbitMQ 服務器
3.無Broker的通訊流派:ZeroMQ 網絡
4.總結架構
咱們知道,目前市面上的MQ包括Kafka、RabbitMQ、ZeroMQ、RocketMQ等等。異步
那麼他們之間究竟有什麼本質區別,分別適用於什麼場景呢?分佈式
上述拋出的問題,一樣在很多公司的Java工程師面試中出現,特別是當你簡歷上的技術棧包含了這些技術,面試官每每喜歡用這個問題,對你進行摸底考察。post
本文咱們就一塊兒來探討一下。性能
這個流派最典型的就是Kafka,Kafka實際上爲了提高性能,簡化了MQ功能模型,僅僅提供了一些最基礎的MQ相關的功能,可是大幅度優化和提高了吞吐量。大數據
首先,這個流派必定是有一個Broker角色的,也就是說,Kafka須要部署一套服務器集羣,每臺機器上都有一個Kafka Broker進程,這個進程就負責接收請求,存儲數據,發送數據。
Kafka的生產消費模型作的相對是比較暴力簡單的,就是簡單的數據流模型。
簡單來講,他有一個概念,叫作「Topic」,你能夠往這個「Topic」裏寫數據,而後讓別人從這裏來消費。
這個Topic能夠劃分爲多個Partition,每一個Partition放一臺機器上,存儲一部分數據。
在寫消息到Topic的時候,會自動把你這個消息給分發到某一個Partition上去。
而後消費消息的時候,有一個Consumer Group的概念,你部署在多臺機器上的Consumer能夠組成一個Group,一個Partition只能給一個Consumer消費,一個Cosumer能夠消費多個Partition,這是最最核心的一點。
經過這個模型,保證一個Topic裏的每條消息,只會交給Consumer Group裏的一個Consumer來消費,造成了一個Queue(隊列)的效果。
假如你想要有一個Queue的效果,也就是但願不停的往Queue裏寫數據,而後多個消費者消費,每條消息就只能給一個消費者,那麼經過Kafka來實現,其實就是生產者寫多個Partition,每一個Partition只能給Consumer Group中的一個Consumer來消費。以下圖所示:
若是要實現Publish/Subscribe的模型呢?就是說生產者發送的每條消息,都要讓全部消費都消費到,怎麼實現?
那就讓每一個消費者都是一個獨立的消費組,這樣每條消息都會發送給全部的消費組,每一個消費組裏那惟一的一個消費者必定會消費到全部的消息。
可是除此以外,Kafka就沒有任何其餘的消費功能了,就是如此簡單,因此屬於一種比較暴力直接的流派。
它就是簡單的消費模型,實現最基礎的Queue和Pub/Sub兩種消費模型,可是內核中大幅度優化和提高了性能以及吞吐量。
因此Kafka天生適合的場景,就是大數據領域的實時數據計算的場景。
由於在大數據的場景下,一般是弱業務的場景,沒有太多複雜的業務系統交互,而主要是大量的數據流入Kafka,而後進行實時計算。
因此就是須要簡單的消費模型,可是必須在內核中對吞吐量和性能進行大幅度的優化。
所以Kafka技術一般是在大數據的實時數據計算領域中使用的,好比說每秒處理幾十萬條消息,甚至每秒處理上百萬條消息。
第二個流派,就是RabbitMQ爲表明的流派,他強調的不是說如何提高性能和吞吐量,關注的是說要提供很是強大、複雜並且完善的消息路由功能。
因此對於RabbitMQ而言,他就不是那麼簡單的Topic-Partition的消費模型了。
在RabbitMQ中引入了一個很是核心的概念,叫作Exchange,這個Exchange就是負責根據複雜的業務規則把消息路由到內部的不一樣的Queue裏去。
舉個例子,若是要實現最簡單的隊列功能,就是讓exchange往一個queue裏寫數據,而後多個消費者來消費這個queue裏的數據,每條消息只能給一個消費者,那麼能夠是相似下面的方式。
若是想要實現Pub/Sub的模型,就是一條消息要被全部的消費者給消費到,那麼就可讓每一個消費者都有一個本身的Queue,而後綁定到一個Exchange上去。
接着,這個Exchange就設定把消息路由給全部的Queue便可,以下面這樣。
此時Exchange能夠把每條消息都路由給全部的Queue,每一個Consumer均可以從本身的Queue裏拿到全部的消息。
RabbitMQ這種流派,其實最核心的是,基於Exchange這個概念,他能夠作不少複雜的事情。
好比:若是你想要某個Consumer只能消費到某一類數據,那麼Exchange能夠把消息裏好比帶「XXX」前綴的消息路由給某個Queue。或者你能夠限定某個Consumer就只能消費某一部分數據。總之在這裏你能夠作不少的限制,設置複雜的路由規則。
可是也正是由於引入了這種複雜的消費模型,支持複雜的路由功能,致使RabbitMQ在內核以及架構設計上無法像Kafka作的那麼的輕量級、高性能、可擴展、高吞吐,因此RabbitMQ在吞吐量上要比Kafka低一個數量級。
因此這種流派的MQ,每每適合用在Java業務系統中,不一樣的業務系統須要進行復雜的消息路由。
好比說業務系統A發送了10條消息,其中3條消息是給業務系統B的,7條消息是給業務系統C的,要實現這種複雜的路由模型,就必須依靠RabbitMQ來實現。
固然,對於這種業務系統之間的消息流轉而言,可能不須要那麼高的吞吐量,可能每秒業務系統之間也就轉發幾十條或者幾百條消息,那麼就徹底適合採用RabbitMQ來實現。
ZeroMQ表明的是第三種MQ。說白了,他是不須要在服務器上部署的,就是一個客戶端的庫而已。
也就是說,他主要是封裝了底層的Socket網絡通信,而後一個系統要發送一條消息給另一個消息消費 。
經過ZeroMQ,本質就是底層ZeroMQ發送一條消息到另一個系統上去。
因此ZeroMQ是去中心化的,不須要跟Kafka、RabbitMQ同樣在服務器上部署的。
他主要是用來進行業務系統之間的網絡通訊的,有點相似於好比你是一個分佈式系統架構,那麼此時分佈式架構中的各個子系統互相之間要通訊,你是基於Dubbo RPC?仍是Spring Cloud HTTP?
可能上述兩種你都不想要,就是要基於原始的Socket進行網絡通訊,簡單的收發消息而已。
此時就可使用ZeroMQ做爲分佈式系統之間的消息通訊,以下面那樣。
其實如今基本上MQ主要就是這三個流派,不少小衆的MQ通常不多有人會用。
並且用MQ的場景主要就是兩大類:
業務系統之間異步通訊
大數據領域的實時數據計算
因此通常業務系統之間通訊就是會採用RabbitMQ/RocketMQ,須要複雜的消息路由功能的支撐。
大數據的實時計算場景會採用Kafka,須要簡單的消費模型,可是超高的吞吐量。
至於ZeroMQ,通常來講,少數分佈式系統中子系統之間的分佈式通訊時會採用,做爲輕量級的異步化的通訊組件。
END
做者簡介:
做者前後工做於滴滴、百度、字節跳動等國內一線互聯網大廠,從事基礎架構相關工做。帶領團隊設計與構建了大規模的分佈式存儲系統、分佈式消息中間件、分佈式數據庫,對分佈式架構設計、系統高可用體系構建、基礎中間件架構都有豐富的經驗。
END
長按下圖二維碼,即刻關注【狸貓技術窩】 阿里、京東、美團、字節跳動 頂尖技術專家坐鎮 爲IT人打造一個 「有溫度」 的技術窩!