1. 程式人生 > 實用技巧 >對戰 | RabbitMq 大戰 kafka

對戰 | RabbitMq 大戰 kafka

Hi! 我是小小,我們今天又見面了,今天主要內容是從十七個方面對比kafka,rabbitmq,zeromq,rocketmq,activemq,更加方便你的技術選型哦!

資料文件

  1. kafaka:在kafka中,有作者自己寫的書,網上的資料也有一點

  2. rabbitmq,多,有很多不錯的數,網路上資料也多。

  3. zeromq,少,沒有專門寫zeromq的書,網上的資料多是程式碼實現和簡單介紹。

  4. rocketmq,少,沒有專門寫rocketmq的數,網路上的良莠不齊,官方文件簡單,但是對技術細節沒有過多的描述。

  5. activemq,多,沒有專門寫activemq的書,網上資料多。

開發語言

kafka:Scala rabbitmq:Erlang zeromq:c rocketmq:Java activemq:Java

支援的協議

  1. kafka 自己定義的一套,基於TCP

  2. rabbitmq:AMQP

  3. zeromq:TCP,UDP

  4. rocketmq:自己定義的一套

  5. activemq:OpenWire,STOMP,REST,XMPP,AMQP

訊息儲存

  1. kafka:記憶體,磁碟,資料庫,支援大量堆積 kafka 的最小儲存單元是分割槽,一個topic包含多個分割槽,kafka建立分割槽的時候,這些分割槽會被分配在多個伺服器上,通常一個節點是一臺伺服器,分割槽會均勻的分佈在不同的伺服器上,分割槽的副本也會均勻的分佈在不同的伺服器上,確保負載均衡以及高可用。當新的節點加入叢集的時候,部分副本會自動遷移到新的節點上,根據配置檔案中的目錄,會自己吧新的分割槽分配非目錄分割槽裡分割槽數最少的目錄。

  2. rabbitmq: 記憶體,磁碟,支援少量堆積 rabbitmq的訊息分為持久化訊息和非持久化訊息,不管是否是不是持久化訊息,其都會寫入到磁盤裡,其中,持久化的訊息也同樣會在記憶體裡儲存一份,這樣做的目的是提高效能。引入了映象佇列機制,可以吧重要的佇列複製到叢集中其他節點上,保證這些佇列訊息不丟失,配置映象佇列,包含一個主節點,master和從節點slave,如果master節點失效,從節點會自動變成主節點。rabbitmq會讓master均勻的分佈在不同的伺服器上,而同一個佇列的slave也會均勻的分佈在不同的伺服器上,保證負載均衡和高可用。

  3. zeromq:訊息傳送端的記憶體或者磁碟中儲存,不支援持久化。

  4. rocketmq:磁碟,支援大量堆積。日誌檔案存放的是實際的訊息資料,每個日誌檔案上限是1G,滿看之後會自動新建一個日誌檔案儲存資料。ConsumeQueue佇列只存放offset,size,tagcode資料,非常小,分佈在多個節點上。其中consumequeue相當於日誌檔案的索引檔案,消費者消費的時候,從consumequeue中查詢訊息的在日誌檔案中查詢到offset,再去commitlog中查詢元資料。

  5. activemq:記憶體,磁碟,資料庫,支援少量堆積。

訊息事物

  1. kafka 支援

  2. rabbitmq:支援,客戶端吧通道設定為事物模式以後,只有當訊息被rabbitmq接收以後,事物才能提交成功,否則進行回滾,

  3. zeromq:不支援

  4. rocketmq:支援

  5. activemq:支援

負載均衡

kafka

  1. 一個節點通常就是一臺伺服器節點。對於同一個Topic的不同分割槽,Kafka會盡力將這些分割槽分佈到不同的節點伺服器上,zookeeper儲存了節點資訊、主題和分割槽的元資料資訊。分割槽首領會處理來自客戶端的生產請求,kafka分割槽首領會被分配到不同的節點伺服器上,讓不同的節點伺服器共同分擔任務。每一個節點都快取了元資料資訊,客戶端可以從任意一個節點獲取元資料資訊並快取起來,根據元資料資訊知道要往哪裡傳送請求。

  2. kafka的消費者組訂閱同一個topic,會盡可能地使得每一個消費者分配到相同數量的分割槽,分攤負載。

  3. 當消費者加入或者退出消費者組的時候,還會觸發再均衡,為每一個消費者重新分配分割槽,分攤負載。

kafka的負載均衡大部分是自動完成的,分割槽的建立也是kafka完成的,隱藏了很多細節,避免了繁瑣的配置和人為疏忽造成的負載問題。4. 傳送端由topic和key來決定訊息發往哪個分割槽,如果key為null,那麼會使用輪詢演算法將訊息均衡地傳送到同一個topic的不同分割槽中。如果key不為null,那麼會根據key的hashcode取模計算出要發往的分割槽。

rabbitmq

對負債均衡支援不好

訊息被投遞到哪個佇列是由交換器和key決定的,交換器、路由鍵、佇列都需要手動建立。

rabbitmq客戶端傳送訊息要和broker建立連線,需要事先知道broker上有哪些交換器,有哪些佇列。通常要宣告要傳送的目標佇列,如果沒有目標佇列,會在broker上建立一個佇列,如果有,就什麼都不處理,接著往這個佇列傳送訊息。假設大部分繁重任務的佇列都建立在同一個broker上,那麼這個broker的負載就會過大。(可以在上線前預先建立佇列,無需宣告要傳送的佇列,但是傳送時不會嘗試建立佇列,可能出現找不到佇列的問題,rabbitmq的備份交換器會把找不到佇列的訊息儲存到一個專門的佇列中,以便以後查詢使用)

使用映象佇列機制建立rabbitmq叢集可以解決這個問題,形成master-slave的架構,master節點會均勻分佈在不同的伺服器上,讓每一臺伺服器分攤負載。slave節點只是負責轉發,在master失效時會選擇加入時間最長的slave成為master。

當新節點加入映象佇列的時候,佇列中的訊息不會同步到新的slave中,除非呼叫同步命令,但是呼叫命令後,佇列會阻塞,不能在生產環境中呼叫同步命令。2. 當rabbitmq佇列擁有多個消費者的時候,佇列收到的訊息將以輪詢的分發方式傳送給消費者。每條訊息只會傳送給訂閱列表裡的一個消費者,不會重複。

這種方式非常適合擴充套件,而且是專門為併發程式設計的。

如果某些消費者的任務比較繁重,那麼可以設定basicQos限制通道上消費者能保持的最大未確認訊息的數量,在達到上限時,rabbitmq不再向這個消費者傳送任何訊息。3. 對於rabbitmq而言,客戶端與叢集建立的TCP連線不是與叢集中所有的節點建立連線,而是挑選其中一個節點建立連線。

但是rabbitmq叢集可以藉助HAProxy、LVS技術,或者在客戶端使用演算法實現負載均衡,引入負載均衡之後,各個客戶端的連線可以分攤到叢集的各個節點之中。

rocketmq

支援負載均衡 一個broker通常是一個伺服器節點,broker分為master和slave,master和slave儲存的資料一樣,slave從master同步資料。

activemq

支援負載均衡,可以基於zookeeper實現負債均衡

管理介面

  1. kafka:一般

  2. rabbitmq:好

  3. zeromq:無

  4. rocketmq:無

  5. activemq:一般

可用性

  1. kafka:非常高

  2. rabbitmq:高

  3. zeromq: 高

  4. rocketmq:非常高

  5. activemq:高

吞吐量

  1. Kafka:極大 Kafka按批次傳送訊息和消費訊息。傳送端將多個小訊息合併,批量發向Broker,消費端每次取出一個批次的訊息批量處理。

  2. rabbitmq:比較大

  3. zeromq:極大

  4. rocketmq:大 rocketMQ接收端可以批量消費訊息,可以配置每次消費的訊息數,但是傳送端不是批量傳送。

  5. activemq:比較大

順序訊息

kafka

Kafka:支援。

設定生產者的max.in.flight.requests.per.connection為1,可以保證訊息是按照發送順序寫入伺服器的,即使發生了重試。

kafka保證同一個分割槽裡的訊息是有序的,但是這種有序分兩種情況

  1. key為null,訊息逐個被寫入不同主機的分割槽中,但是對於每個分割槽依然是有序的

  2. key不為null , 訊息被寫入到同一個分割槽,這個分割槽的訊息都是有序。

rabbitmq

rabbitmq:不支援

zeromq

zeromq:不支援

rocketmq

rocketmq:支援

activemq

activemq:不支援

併發度

kafka

Kafka:高

一個執行緒一個消費者,kafka限制消費者的個數要小於等於分割槽數,如果要提高並行度,可以在消費者中再開啟多執行緒,或者增加consumer例項數量。

rabbitmq

rabbitmq:極高

本身是用Erlang語言寫的,併發效能高。

zeromq

zeromq:高

rocketmq

rocketmq:高

  1. rocketmq限制消費者的個數少於等於佇列數,但是可以在消費者中再開啟多執行緒,這一點和kafka是一致的,提高並行度的方法相同。

  2. 同一個網路連線connection,客戶端多個執行緒可以同時傳送請求,連線會被複用,減少效能開銷。

activemq

activemq:高

單個ActiveMQ的接收和消費訊息的速度在1萬筆/秒(持久化 一般為1-2萬, 非持久化 2 萬以上),在生產環境中部署10個Activemq就能達到10萬筆/秒以上的效能,部署越多的activemq broker 在MQ上latency也就越低,系統吞吐量也就越高。

關於作者

一位生於二線,活在一線的程式猿,我是小小,我們下期再見。

小明菜市場

推薦閱讀

執行流程 | 你真的瞭解Spring AOP的執行順序嗎?

吊打面試官 | Java到底是值傳遞還是引用傳遞

容器 | Docker 如此之好,你為什麼還要用k8s

分散式ID | 這六種分散式ID生成方法,總有一款適合你

資料結構與演算法 | 來來來,讓我們重新認識一下什麼是樹

給我個好看再走好嗎?