作者:愛釣魚的桌子哥,阿里巴巴高階技術專家
目錄
(1)流派1:有Broker的暴力路由
(2)流派2:有Broker的複雜路由
(3)流派3:無Broker的通訊流派
(4)總結
作者:愛釣魚的桌子哥,資深架構師
平時經常會看到很多人寫文章分析Kafka、RabbitMQ、RocketMQ等各種MQ之間的效能比較,功能比較,但是實際上從MQ訊息佇列的門派上來說,這些MQ其實是分屬不同的門派的。
那麼這不同的門派之間,到底有什麼區別呢?
(1)流派1:有Broker的暴力路由
這個流派最典型的就是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技術通常是在大資料的實時資料計算領域中使用的,比如說每秒處理幾十萬條訊息,甚至每秒處理上百萬條訊息。
(2)流派2:有Broker的複雜路由
第二個流派,就是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來實現。
(3)流派3:無Broker的通訊流派
ZeroMQ代表的是第三種MQ。說白了,他是不需要在伺服器上部署的,就是一個客戶端的庫而已。
也就是說,他主要是封裝了底層的Socket網路通訊,然後一個系統要傳送一條訊息給另外一個訊息消費 。
通過ZeroMQ,本質就是底層ZeroMQ傳送一條訊息到另外一個系統上去。
所以ZeroMQ是去中心化的,不需要跟Kafka、RabbitMQ一樣在伺服器上部署的。
他主要是用來進行業務系統之間的網路通訊的,有點類似於比如你是一個分散式系統架構,那麼此時分散式架構中的各個子系統互相之間要通訊,你是基於Dubbo RPC?還是Spring Cloud HTTP?
可能上述兩種你都不想要,就是要基於原始的Socket進行網路通訊,簡單的收發訊息而已。
此時就可以使用ZeroMQ作為分散式系統之間的訊息通訊,如下面那樣。
(4)總結
其實現在基本上MQ主要就是這三個流派,很多小眾的MQ一般很少有人會用。
而且用MQ的場景主要就是兩大類:
業務系統之間非同步通訊
大資料領域的實時資料計算
所以一般業務系統之間通訊就是會採用RabbitMQ/RocketMQ,需要複雜的訊息路由功能的支撐。
大資料的實時計算場景會採用Kafka,需要簡單的消費模型,但是超高的吞吐量。
至於ZeroMQ,一般來說,少數分散式系統中子系統之間的分散式通訊時會採用,作為輕量級的非同步化的通訊元件。
作者簡介:
作者先後工作於滴滴、百度、位元組跳動等國內一線網際網路大廠,從事基礎架構相關工作。帶領團隊設計與構建了大規模的分散式儲存系統、分散式訊息中介軟體、分散式資料庫,對分散式架構設計、系統高可用體系構建、基礎中介軟體架構都有豐富的經驗。
END
長按下圖二維碼,即刻關注【狸貓技術窩】 阿里、京東、美團、位元組跳動 頂尖技術專家坐鎮 為IT人打造一個 “有溫度” 的技術窩!