RabbitMQ 和 Kafka 到底怎麼選?

前言 java

開源社區有好多優秀的隊列中間件,好比RabbitMQ和Kafka,每一個隊列都貌似有其特性,在進行工程選擇時,每每眼花繚亂,不知所措。對於RabbitMQ和Kafka,到底應該選哪一個?面試

RabbitMQ架構數據庫

RabbitMQ是一個分佈式系統,這裏面有幾個抽象概念。後端

  • broker:每一個節點運行的服務程序,功能爲維護該節點的隊列的增刪以及轉發隊列操做請求。
  • master queue:每一個隊列都分爲一個主隊列和若干個鏡像隊列。
  • mirror queue:鏡像隊列,做爲master queue的備份。在master queue所在節點掛掉以後,系統把mirror queue提高爲master queue,負責處理客戶端隊列操做請求。注意,mirror queue只作鏡像,設計目的不是爲了承擔客戶端讀寫壓力。

如上圖所示,集羣中有兩個節點,每一個節點上有一個broker,每一個broker負責本機上隊列的維護,而且borker之間能夠互相通訊。集羣中有兩個隊列A和B,每一個隊列都分爲master queue和mirror queue(備份)。那麼隊列上的生產消費怎麼實現的呢?消息隊列的應用場景能夠看這篇文章《消息隊列常見的幾種使用場景介紹》多線程

隊列消費架構

如上圖有兩個consumer消費隊列A,這兩個consumer連在了集羣的不一樣機器上。RabbitMQ集羣中的任何一個節點都擁有集羣上全部隊列的元信息,因此鏈接到集羣中的任何一個節點均可以,主要區別在於有的consumer連在master queue所在節點,有的連在非master queue節點上。分佈式

由於mirror queue要和master queue保持一致,故須要同步機制,正由於一致性的限制,致使全部的讀寫操做都必須都操做在master queue上(想一想,爲啥讀也要從master queue中讀?和數據庫讀寫分離是不同的。),而後由master節點同步操做到mirror queue所在的節點。即便consumer鏈接到了非master queue節點,該consumer的操做也會被路由到master queue所在的節點上,這樣才能進行消費。工具

隊列生產性能

原理和消費同樣,若是鏈接到非 master queue 節點,則路由過去。優化

因此,到這裏小夥伴們就能夠看到 RabbitMQ的不足:因爲master queue單節點,致使性能瓶頸,吞吐量受限。雖然爲了提升性能,內部使用了Erlang這個語言實現,可是終究擺脫不了架構設計上的致命缺陷。

Kafka

說實話,Kafka我以爲就是看到了RabbitMQ這個缺陷才設計出的一個改進版,改進的點就是:把一個隊列的單一master變成多個master,即一臺機器扛不住qps,那麼我就用多臺機器扛qps,把一個隊列的流量均勻分散在多臺機器上不就能夠了麼?注意,多個master之間的數據沒有交集,即一條消息要麼發送到這個master queue,要麼發送到另一個master queue。

這裏面的每一個master queue 在Kafka中叫作Partition,即一個分片。一個隊列有多個主分片,每一個主分片又有若干副分片作備份,同步機制相似於RabbitMQ。

如上圖,咱們省略了不一樣的queue,假設集羣上只有一個queue(Kafka中叫Topic)。每一個生產者隨機把消息發送到主分片上,以後主分片再同步給副分片。

隊列讀取的時候虛擬出一個Group的概念,一個Topic內部的消息,只會路由到同Group內的一個consumer上,同一個Group中的consumer消費的消息是不同的;Group之間共享一個Topic,看起來就是一個隊列的多個拷貝。因此,爲了達到多個Group共享一個Topic數據,Kafka並不會像RabbitMQ那樣消息消費完畢立馬刪除,而是必須在後臺配置保存日期,即只保存最近一段時間的消息,超過這個時間的消息就會從磁盤刪除,這樣就保證了在一個時間段內,Topic數據對全部Group可見(這個特性使得Kafka很是適合作一個公司的數據總線)。隊列讀一樣是讀主分片,而且爲了優化性能,消費者與主分片有一一的對應關係,若是消費者數目大於分片數,則存在某些消費者得不到消息。

因而可知,Kafka絕對是爲了高吞吐量設計的,好比設置分片數爲100,那麼就有100臺機器去扛一個Topic的流量,固然比RabbitMQ的單機性能好。

總結

本文只作了Kafka和RabbitMQ的對比,可是開源隊列豈止這兩個,ZeroMQ,RocketMQ,JMQ等等,時間有限也就沒有細看,故不在本文比較範圍以內。

因此,別再被這些五花八門的隊列迷惑了,從架構上找出關鍵差異,並結合本身的實際需求(好比本文就只單單從吞吐量一個需求來考察)輕輕鬆鬆搞定選型。最後總結以下:

  • 吞吐量較低:Kafka和RabbitMQ均可以。
  • 吞吐量高:Kafka。

本文內容參考自RabbitMQ和KafKa官方文檔,因此真要搞懂一箇中間件的原理最好去看官方文檔,文檔裏面有詳細的設計方案,咱們能夠本身進行設計方案的對比,從而找出符合本身實際狀況的中間件。

推薦去個人博客閱讀更多:

1.Java JVM、集合、多線程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、後端、架構、阿里巴巴等大廠最新面試題

生活很美好,明天見~

相關文章
相關標籤/搜索