前言
在分佈式系統中,咱們普遍運用消息中間件進行系統間的數據交換,便於異步解耦。如今開源的消息中間件有不少,前段時間產品 RocketMQ (MetaQ的內核) 也順利開源,獲得你們的關注。java
概念
MQ簡介
MQ,Message queue,消息隊列,就是指保存消息的一個容器。具體的定義這裏就不相似於數據庫、緩存等,用來保存數據的。固然,與數據庫、緩存等產品比較,也有本身一些特色,具體的特色後文會作詳細的介紹。
如今經常使用的MQ組件有ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、MetaMQ,固然近年來火熱的kafka,從某些場景來講,也是MQ,固然kafka的功能更增強大,雖然不一樣的MQ都有本身的特色和優點,可是,無論是哪一種MQ,都有MQ自己自帶的一些特色,下面,介紹MQ的特色。redis
MQ特色
一、先進先出
不能先進先出,都不能說是隊列了。消息隊列的順序在入隊的時候就基本已經肯定了,通常是不需人工干預的。並且,最重要的是,數據是隻有一條數據在使用中。 這也是MQ在諸多場景被使用的緣由。
二、發佈訂閱
發佈訂閱是一種很高效的處理方式,若是不發生阻塞,基本能夠當作是同步操做。這種處理方式能很是有效的提高服務器利用率,這樣的應用場景很是普遍。
三、持久化
持久化確保MQ的使用不僅是一個部分場景的輔助工具,而是讓MQ能像數據庫同樣存儲核心的數據。
四、分佈式
在如今大流量、大數據的使用場景下,只支持單體應用的服務器軟件基本是沒法使用的,支持分佈式的部署,才能被普遍使用。並且,MQ的定位就是一個高性能的中間件。
應用場景算法
那麼,消息中間件性能究竟哪家強?
帶着這個疑問,咱們中間件測試組對常見的三類消息產品(Kafka、RabbitMQ、RocketMQ)作了性能比較。數據庫
Kafka
Kafka是LinkedIn開源的分佈式發佈-訂閱消息系統,目前歸屬於Apache頂級項目。Kafka主要特色是基於Pull的模式來處理消息消費,追求高吞吐量,一開始的目的就是用於日誌收集和傳輸。0.8版本開始支持複製,不支持事務,對消息的重複、丟失、錯誤沒有嚴格要求,適合產生大量數據的互聯網服務的數據收集業務。編程
RabbitMQ
RabbitMQ是使用Erlang語言開發的開源消息隊列系統,基於AMQP協議來實現。AMQP的主要特徵是面向消息、隊列、路由(包括點對點和發佈/訂閱)、可靠性、安全。AMQP協議更多用在企業系統內,對數據一致性、穩定性和可靠性要求很高的場景,對性能和吞吐量的要求還在其次。緩存
RocketMQ
RocketMQ是阿里開源的消息中間件,它是純Java開發,具備高吞吐量、高可用性、適合大規模分佈式系統應用的特色。RocketMQ思路起源於Kafka,但並非Kafka的一個Copy,它對消息的可靠傳輸及事務性作了優化,目前在阿里集團被普遍應用於交易、充值、流計算、消息推送、日誌流式處理、binglog分發等場景。安全
測試目的
對比Kafka、RabbitMQ、RocketMQ發送小消息(124字節)的性能。此次壓測咱們只關注服務端的性能指標,因此壓測的標準是:服務器
不斷增長髮送端的壓力,直到系統吞吐量再也不上升,而響應時間拉長。這時服務端已出現性能瓶頸,能夠得到相應的系統最佳吞吐量。架構
測試場景
在同步發送場景中,三個消息中間件的表現區分明顯:併發
Kafka
Kafka的吞吐量高達17.3w/s,不愧是高吞吐量消息中間件的行業老大。這主要取決於它的隊列模式保證了寫磁盤的過程是線性IO。此時broker磁盤IO已達瓶頸。
RocketMQ
RocketMQ也表現不俗,吞吐量在11.6w/s,磁盤IO %util已接近100%。RocketMQ的消息寫入內存後即返回ack,由單獨的線程專門作刷盤的操做,全部的消息均是順序寫文件。
RabbitMQ
RabbitMQ的吞吐量5.95w/s,CPU資源消耗較高。它支持AMQP協議,實現很是重量級,爲了保證消息的可靠性在吞吐量上作了取捨。咱們還作了RabbitMQ在消息持久化場景下的性能測試,吞吐量在2.6w/s左右。
測試結論
在服務端處理同步發送的性能上,Kafka>RocketMQ>RabbitMQ。
附錄:
測試環境
服務端爲單機部署,機器配置以下:
應用版本:
測試腳本
消息隊列優勢對比
前面咱們對比了最簡單的小消息發送場景,Kafka暫時勝出。可是,做爲經受過歷次雙十一洗禮的RocketMQ,在互聯網應用場景中更有它優越的一面。
RabbitMQ
是使用Erlang編寫的一個開源的消息隊列,自己支持不少的協議:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它變的很是重量級,更適合於企業級的開發。同時實現了一個經紀人(Broker)構架,這意味着消息在發送給客戶端時先在中心隊列排隊。對路由(Routing),負載均衡(Load balance)或者數據持久化都有很好的支持。
Redis
是一個Key-Value的NoSQL數據庫,開發維護很活躍,雖然它是一個Key-Value數據庫存儲系統,但它自己支持MQ功能,因此徹底能夠當作一個輕量級的隊列服務來使用。對於RabbitMQ和Redis的入隊和出隊操做,各執行100萬次,每10萬次記錄一次執行時間。測試數據分爲128Bytes、512Bytes、1K和10K四個不一樣大小的數據。實驗代表:入隊時,當數據比較小時Redis的性能要高於RabbitMQ,而若是數據大小超過了10K,Redis則慢的沒法忍受;出隊時,不管數據大小,Redis都表現出很是好的性能,而RabbitMQ的出隊性能則遠低於Redis。
ZeroMQ
號稱最快的消息隊列系統,尤爲針對大吞吐量的需求場景。ZMQ可以實現RabbitMQ不擅長的高級/複雜的隊列,可是開發人員須要本身組合多種技術框架,技術上的複雜度是對這MQ可以應用成功的挑戰。ZeroMQ具備一個獨特的非中間件的模式,你不須要安裝和運行一個消息服務器或中間件,由於你的應用程序將扮演了這個服務角色。你只須要簡單的引用ZeroMQ程序庫,可使用NuGet安裝,而後你就能夠愉快的在應用程序之間發送消息了。可是ZeroMQ僅提供非持久性的隊列,也就是說若是down機,數據將會丟失。其中,Twitter的Storm中使用ZeroMQ做爲數據流的傳輸。
ActiveMQ
Apache ActiveMQ 是最受歡迎且功能最強大的開源消息傳遞和Integration Patterns服務器。
Apache ActiveMQ速度快,支持許多跨語言客戶端和協議,帶有易於使用的企業集成模式和許多高級功能,同時徹底支持JMS 1.1和J2EE 1.4。Apache ActiveMQ是在Apache 2.0許可下發布
特徵
支持Java消息服務(JMS) 1.1 版本
Spring Framework
集羣 (Clustering)
支持的編程語言包括:C、C++、C#、Delphi、Erlang、Adobe Flash、Haskell、Java、JavaScript、Perl、PHP、Pike、Python和Ruby
協議支持包括:OpenWire、REST、STOMP、WS-Notification、MQTT、XMPP以及AMQP [1]
Jafka/Kafka
Kafka是Apache下的一個子項目,是一個高性能跨語言分佈式Publish/Subscribe消息隊列系統,而Jafka是在Kafka之上孵化而來的,即Kafka的一個升級版。具備如下特性:快速持久化,能夠在O(1)的系統開銷下進行消息持久化;高吞吐,在一臺普通的服務器上既能夠達到10W/s的吞吐速率;徹底的分佈式系統,Broker、Producer、Consumer都原生自動支持分佈式,自動實現複雜均衡;支持Hadoop數據並行加載,對於像Hadoop的同樣的日誌數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。Kafka經過Hadoop的並行加載機制來統一了在線和離線的消息處理,這一點也是本課題所研究系統所看重的。Apache Kafka相對於ActiveMQ是一個很是輕量級的消息系統,除了性能很是好以外,仍是一個工做良好的分佈式系統。
其餘對比
Rabbitmq比kafka可靠,kafka更適合IO高吞吐的處理,好比ELK日誌收集
Kafka和RabbitMq同樣是通用意圖消息代理,他們都是以分佈式部署爲目的。可是他們對消息語義模型的定義的假設是很是不一樣的。我對"AMQP 更成熟"這個論點是持懷疑態度的。讓咱們用事實說話來看看用什麼解決方案來解決你的問題。
a) 如下場景你比較適合使用Kafka。你有大量的事件(10萬以上/秒)、你須要以分區的,順序的,至少傳遞成功一次到混雜了在線和打包消費的消費者、你但願能重讀消息、你能接受目前是有限的節點級別高可用或則說你並不介意經過論壇/IRC工具獲得還在幼兒階段的軟件的支持。
b) 如下場景你比較適合使用RabbitMQ。你有較少的事件(2萬以上/秒)而且須要經過複雜的路由邏輯去找到消費者、你但願消息傳遞是可靠的、你並不關心消息傳遞的順序、你須要如今就支持集羣-節點級別的高可用或則說你須要7*24小時的付費支持(固然也能夠經過論壇/IRC工具)。
redis 消息推送是基於分佈式 pub/sub,多用於實時性較高的消息推送,並不保證可靠。
redis 消息推送(基於分佈式 pub/sub)多用於實時性較高的消息推送,並不保證可靠。其餘的mq和kafka保證可靠但有一些延遲(非實時系統沒有保證延遲)。redis-pub/sub斷電就清空,而使用redis-list做爲消息推送雖然有持久化,可是又太弱智,也並不是徹底可靠不會丟。另一點,redis 發佈訂閱除了表示不一樣的 topic 外,並不支持分組,好比kafka中發佈一個東西,多個訂閱者能夠分組,同一個組裏只有一個訂閱者會收到該消息,這樣能夠用做負載均衡。好比,kafka 中發佈:topic = 「發佈帖子」 data=「文章1」 這個消息,後面有一百臺服務器每臺服務器都是一個訂閱者,都訂閱了這個 topic,可是他們可能分爲三組,A組50臺,用來真的作發佈文章,A組50臺裏全部 subscriber 都訂閱了這個topic。因爲在同一組,這條消息 (topic=「發佈帖子」, data=「文章1」)只會被A組裏面一臺當前空閒的機器收到。而B組25臺服務器用於統計,C組25臺服務器用於存檔備份,每組只有一臺會收到。用不一樣的組來決定每條消息要抄送出多少分去,用同組內哪些訂閱者忙,哪些訂閱者空閒來決定消息會被分到哪臺服務器去處理,生產者消費者模型嘛。redis徹底沒有這類機制,這兩點是最大的區別。
redis主要作內存數據庫
redis做者作內存數據庫基礎上增長了消息pub/sub。mq通常都採用訂閱~發佈模型,若是你考慮性能,主要關注點就放在消費模型是pull仍是push。影響最大的,應該是存儲結構。kafka的性能要在topic數量小於64的時候,才能發揮威力。partition決定的。極限狀況下丟消息,例如:主寫入消息後,主機器宕機,並硬盤損壞。review代碼的時候發現的。rabbit不知道,可是rocket的性能是(萬條每秒),而且可以橫向無限擴展,單機topic數量在256時,性能損失較小。rocket能夠說是kafka的變種,是阿里在充分reviewkafka代碼後,開發的metaQ。在不斷更新,修補之後,阿里把metaQ3.0改名爲rocket,而且rocket是java寫的易於維護。另外就是rocket和kafka有相似無限堆積的能力。想一想,斷電不丟消息,積壓兩億條消息毫無壓力,niubility kafka和rocket mq性能根本不須要考慮的問題。
在應用場景方面,
RabbitMQ
RabbitMQ遵循AMQP協議,由內在高併發的erlanng語言開發,用在實時的對可靠性要求比較高的消息傳遞上,適合企業級的消息發送訂閱,也是比較受到你們歡迎的。
kafka
kafka是Linkedin於2010年12月份開源的消息發佈訂閱系統,它主要用於處理活躍的流式數據,大數據量的數據處理上。經常使用日誌採集,數據採集上。
ActiveMQ
異步調用
一對多通訊
作多個系統的集成,同構、異構
做爲RPC的替代
多個應用相互解耦
做爲事件驅動架構的幕後支撐
爲了提升系統的可伸縮性
在架構模型方面,
RabbitMQ
RabbitMQ遵循AMQP協議,RabbitMQ的broker由Exchange,Binding,queue組成,其中exchange和binding組成了消息的路由鍵;客戶端Producer經過鏈接channel和server進行通訊,Consumer從queue獲取消息進行消費(長鏈接,queue有消息會推送到consumer端,consumer循環從輸入流讀取數據)。rabbitMQ以broker爲中心;有消息的確認機制。
kafka
kafka聽從通常的MQ結構,producer,broker,consumer,以consumer爲中心,消息的消費信息保存的客戶端consumer上,consumer根據消費的點,從broker上批量pull數據;無消息確認機制。
在吞吐量,
kafka
kafka具備高的吞吐量,內部採用消息的批量處理,zero-copy機制,數據的存儲和獲取是本地磁盤順序批量操做,具備O(1)的複雜度,消息處理的效率很高。
rabbitMQ
rabbitMQ在吞吐量方面稍遜於kafka,他們的出發點不同,rabbitMQ支持對消息的可靠的傳遞,支持事務,不支持批量的操做;基於存儲的可靠性的要求存儲能夠採用內存或者硬盤。
在可用性方面,
rabbitMQ
rabbitMQ支持miror的queue,主queue失效,miror queue接管。
kafka
kafka的broker支持主備模式。
在集羣負載均衡方面,
kafka
kafka採用zookeeper對集羣中的broker、consumer進行管理,能夠註冊topic到zookeeper上;經過zookeeper的協調機制,producer保存對應topic的broker信息,能夠隨機或者輪詢發送到broker上;而且producer能夠基於語義指定分片,消息發送到broker的某分片上。
rabbitMQ
rabbitMQ的負載均衡須要單獨的loadbalancer進行支持。
其餘
Kafka是可靠的分佈式日誌存儲服務。用簡單的話來講,你能夠把Kafka看成可順序寫入的一大卷磁帶, 能夠隨時倒帶,快進到某個時間點重放。先說下日誌的定義:日誌是數據庫的核心,是對數據庫的全部變動的嚴格有序記錄,「表」是變動的結果。日誌的其餘名字有: Changelog, Write Ahead Log, Commit Log, Redo Log, Journaling.Kafka的特徵以下:高寫入速度:Kafka能以超過1Gbps NIC的速度寫這盤磁帶(實際能夠到SATA 3速度,參考Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)),充分利用了磁盤的物理特性,即,隨機寫入慢(磁頭衝停),順序寫入快(磁頭懸浮)。高可靠性: 經過zookeeper作分佈式一致性,同步到任意多塊磁盤上,故障自動切換選主,自愈。高容量:經過橫向擴展,LinkedIn每日經過Kafka存儲的新增數據高達175TB,8000億條消息,可無限擴容,相似把兩條磁帶粘到一塊兒。傳統業務數據庫的根本缺陷在於:1. 太慢,讀寫太昂貴,沒法避免的隨機尋址。(磁盤最快5ms尋址,固態又太昂貴。)2. 根本沒法適應持續產生的數據流,越用越慢。(索引效率問題)3. 沒法水平scale。(多半是讀寫分離,一主多備。另: NewSQL經過一致性算法,有多主。)針對這些問題,Kafka提出了一種方法: 「log-centric approach(以日誌爲中心的方法)。」將傳統數據庫分爲兩個獨立的系統,即日誌系統和索引系統。「持久化和索引分開,日誌儘量快的落地,索引按照本身的速度追趕。」在數據可靠性在獲得Kafka這種快速的,相似磁帶順序記錄方式保障的大前提下。數據的呈現,使用方式變得很是靈活,能夠根據須要將數據流同時送入搜索系統,RDBMS系統,數據倉庫系統, 圖數據庫系統,日誌分析等這些各類不一樣的數據庫系統。 這些不一樣的系統只不過是一種對Kafka磁帶數據的一種詮釋,一個側面,一個索引,一個快照。數據丟了,不要緊,重放一遍磁帶便可,更多的時候,對這些各式數據庫系統的維護只是須要按期作一個快照,並拷貝到一個安全的對象存儲(如S3) 而已。 一句話:「日誌都是相同的日誌,索引各有各的不一樣。」關於流計算:在以流爲基本抽象的存儲模型下,數據流和數據流之間,能夠多流混合處理,或者流和狀態,狀態和狀態的JOIN處理,這就是Kafka Stream提供的功能。 一個簡單的例子是,在用戶觸發了某個事件後,和用戶表混合處理,產生數據增補(Augment),再進入數據倉庫進行相關性分析,一些簡單的窗口統計和實時分析也很容易就能知足,好比 在收到用戶登陸消息的時候,在線人數+1, 離線的時候-1,反應出當前系統的在線用戶總數。
這方面能夠參考PipelineDB https://www.pipelinedb.com/Kafka
參考文章:http://jm.taobao.org/2016/04/01/kafka-vs-rabbitmq-vs-rocketmq-message-send-performance/?utm_source=tuicool&utm_medium=referral
————————————————版權聲明:本文爲CSDN博主「BraveSoul360」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/yunfeng482/article/details/72856762