一文幫你選擇開(kāi)源消息中間件
現(xiàn)代開(kāi)源消息中間件對(duì)比:
#NATS:
https://nats.io/
https://github.com/nats-io/nats-streaming-serverNATS 最初是使用Ruby構(gòu)建的,每秒可實(shí)現(xiàn)150k消息的消費(fèi)速度。 該團(tuán)隊(duì)用Go中重寫(xiě)了它,現(xiàn)在您可以每秒神奇地發(fā)送8-11百萬(wàn)條消息。 它可以用作發(fā)布-訂閱引擎,但是您也可以把它用于綜合排隊(duì)。
優(yōu)點(diǎn):口號(hào):始終可用,撥號(hào)音簡(jiǎn)潔,設(shè)計(jì)低CPU消耗,快速:高速通信總線,高可用性,高可擴(kuò)展性,輕巧:體積很小,只有3MB Docker映像!
缺點(diǎn):忘卻,沒(méi)有持久性:NATS不進(jìn)行持久性消息傳遞; 如果您處于離線狀態(tài),則不會(huì)收到消息。 沒(méi)有事務(wù),沒(méi)有增強(qiáng)的交付方式,沒(méi)有企業(yè)排隊(duì)。
總的來(lái)說(shuō),NATS和Redis更適合較小的消息(遠(yuǎn)低于1MB),其中延遲通常在不到毫秒的時(shí)間內(nèi)達(dá)到四個(gè)9. NATS不是HTTP,它是擁有它自己的非常簡(jiǎn)單的基于文本的協(xié)議,類似于RPC 。 因此,它不會(huì)在郵件信封中添加任何標(biāo)題。
NATS沒(méi)有復(fù)制,分片或整體訂購(gòu)。 使用NATS,隊(duì)列可以有效地按節(jié)點(diǎn)分片。 如果節(jié)點(diǎn)死亡,則其消息將丟失。 到活動(dòng)節(jié)點(diǎn)的傳入消息仍將傳遞給已連接的訂戶,并且訂戶應(yīng)重新連接到可用節(jié)點(diǎn)池。 一旦先前死掉的節(jié)點(diǎn)重新加入,它將開(kāi)始接收消息。在這種情況下,NATS會(huì)替換HAProxy之類的內(nèi)容; 一個(gè)簡(jiǎn)單的內(nèi)存路由器,用于請(qǐng)求后端。
NATS的用戶包括Buzzfeed,Tinder,Stripe,Rakutan,Ericsson,HTC,Siemens,VMware,Pivotal,GE和Baidu。一個(gè)用例:“我們使用NATS進(jìn)行同步通信,每秒通過(guò)它發(fā)送約1萬(wàn)條消息。 。 必須說(shuō),即使負(fù)載更大(超過(guò)10MB),穩(wěn)定性也很高。 我們已經(jīng)在生產(chǎn)環(huán)境中運(yùn)行了幾周,并且沒(méi)有任何問(wèn)題。 主要限制是沒(méi)有大規(guī)模集群。 您可以擁有一個(gè)非常強(qiáng)大的集群,但是每個(gè)節(jié)點(diǎn)只能轉(zhuǎn)發(fā)一次,這是有限制的。”
#RabbitMQ:
RabbitMQ是遵循AMQP 0.9.1標(biāo)準(zhǔn)的代理消息傳遞引擎。 它遵循標(biāo)準(zhǔn)的存儲(chǔ)轉(zhuǎn)發(fā)模式,您可以選擇將數(shù)據(jù)存儲(chǔ)在RAM中,在磁盤上,或是在這兩者中。 它支持各種消息路由范例。 RabbitMQ可以以集群方式進(jìn)行部署以提高性能,而可以通過(guò)鏡像方式進(jìn)行部署,以實(shí)現(xiàn)高可用性。 消費(fèi)者直接在隊(duì)列上偵聽(tīng),但是發(fā)布者只知道“交換”。這些交換通過(guò)綁定(指定路由范式)與綁定鏈接到隊(duì)列。 綁定隊(duì)列和事務(wù)傳遞語(yǔ)義。 因此,RabbitMQ是一種更為“重量級(jí)”的排隊(duì)解決方案,并為此付出額外的費(fèi)用。
缺點(diǎn):RabbitMQ的高可用性支持非常糟糕。 無(wú)論您如何轉(zhuǎn)動(dòng),它都是單點(diǎn)故障,因?yàn)樗鼰o(wú)法合并因?yàn)榉謪^(qū)情況而導(dǎo)致的沖突隊(duì)列。 分區(qū)不僅會(huì)在網(wǎng)絡(luò)中斷時(shí)發(fā)生,還會(huì)在高負(fù)載情況下發(fā)生。RabbitMQ不會(huì)將消息持久保存到磁盤。
#Kafka:
基于Scala
使用Kafka,您可以進(jìn)行實(shí)時(shí)處理和批處理。 Kafka在JVM上運(yùn)行(具體來(lái)說(shuō)是Scala)。 攝取大量數(shù)據(jù),通過(guò)發(fā)布-訂閱(或排隊(duì))路由。 Broker對(duì)消費(fèi)者幾乎一無(wú)所知。 真正存儲(chǔ)的只是一個(gè)“偏移”值,該值指定使用者在日志中保留的位置。 與許多假定消費(fèi)者主要在線的集成代理不同,Kafka可以成功保存大量數(shù)據(jù)并支持“重播”方案。 該體系結(jié)構(gòu)非常獨(dú)特。 主題按分區(qū)排列(用于并行性),分區(qū)跨節(jié)點(diǎn)復(fù)制(以實(shí)現(xiàn)高可用性)。
與Kafka相比,NATS是一個(gè)很小的基礎(chǔ)架構(gòu),獨(dú)角獸初創(chuàng)公司,物聯(lián)網(wǎng),健康和大型金融組織(LinkedIn,F(xiàn)B,Netflix,GE,美國(guó)銀行,房利美,大通銀行等)都使用Kafka。與Nats相比,Kafka更成熟,并且在巨大的數(shù)據(jù)流中表現(xiàn)出色。NATSServer相比Kafka具有部分功能,因?yàn)樗鼘W⒂讵M窄的用例集。 NATS被設(shè)計(jì)用于以下場(chǎng)景:高性能和低延遲至關(guān)重要,但是如果需要,可以丟失一些數(shù)據(jù),以跟上數(shù)據(jù)的步伐-NATS文檔將其描述為“一勞永逸”。從結(jié)構(gòu)上講,這是因?yàn)镹ATS沒(méi)有持久性層可用于持久存儲(chǔ)數(shù)據(jù),而Kafka卻具有持久性層(使用群集中的存儲(chǔ))。為了完全確保消息不會(huì)丟失,它看起來(lái)像您需要將隊(duì)列聲明為持久+將您的消息標(biāo)記為持久+使用發(fā)布者確認(rèn)。這花費(fèi)了數(shù)百毫秒的延遲。
對(duì)于分區(qū)而言,相對(duì)安全的唯一隊(duì)列或發(fā)布/訂閱系統(tǒng)是Kafka。 當(dāng)您需要5至50臺(tái)服務(wù)器時(shí),Kafka就是一個(gè)非常可靠的工程。 擁有那么多服務(wù)器,您每秒可以處理數(shù)百萬(wàn)條消息,這通常對(duì)于中型公司而言已經(jīng)足夠。
由于多種原因,Kafka完全不適合RPC。 首先,它的數(shù)據(jù)模型將隊(duì)列中的數(shù)據(jù)分片,每個(gè)分區(qū)只能由一個(gè)使用者使用。 假設(shè)我們有分區(qū)1和2。P1為空,P2有大量消息。 現(xiàn)在,當(dāng)C2工作時(shí),您將擁有一個(gè)空閑的使用者C1。 C1無(wú)法承擔(dān)C2的任何工作,因?yàn)樗荒芴幚碜约旱姆謪^(qū)。 換句話說(shuō):一個(gè)緩慢的使用者可以阻塞隊(duì)列的很大一部分。 Kafka專為快速(或至少表現(xiàn)均勻)的消費(fèi)者而設(shè)計(jì)。
- NATS與Kafka的關(guān)系
NATS最近加入了CNCF(托管Kubernetes,Prometheus等項(xiàng)目-在這里查看Golang的優(yōu)勢(shì)!)協(xié)議-Kafka是基于TCP的二進(jìn)制文件,而不是NATS是簡(jiǎn)單文本(也基于TCP)的消息傳遞模式-兩者都支持發(fā)布/訂閱和隊(duì)列,但是NATS也支持請(qǐng)求-應(yīng)答(同步和異步)。NATS具有隊(duì)列的概念(當(dāng)然具有唯一的名稱),并且掛接到同一隊(duì)列的所有訂戶最終都成為一部分屬于同一隊(duì)列組。 (可能多個(gè))訂閱者中只有一個(gè)收到消息。多個(gè)此類隊(duì)列組也將接收同一組消息。這使其成為混合的發(fā)布-訂閱(一對(duì)多)和隊(duì)列(點(diǎn)對(duì)點(diǎn))。 Kafka通過(guò)消費(fèi)者組支持相同的事物,這些用戶組可以從一個(gè)或多個(gè)主題中提取數(shù)據(jù)。流處理— NATS不像Kafka那樣對(duì)Kafka Streams提供一流的功能,因此不支持流處理。相對(duì)于NATS,NATS提取消息的方式與服務(wù)器本身將消息路由到客戶端的NATS(內(nèi)部維護(hù)興趣圖)相對(duì)。NATS可以采取敏感措施,因?yàn)樗梢郧袛嗖环仙a(chǎn)速度的消費(fèi)者,以及不響應(yīng)心跳請(qǐng)求的客戶。消費(fèi)者活躍度檢查也由Kafka執(zhí)行。這是從客戶端本身完成/啟動(dòng)的,因此可能會(huì)導(dǎo)致復(fù)雜的情況(例如,當(dāng)您處于消息處理循環(huán)中且未輪詢時(shí))。有很多配置參數(shù)(在客戶端上)可調(diào)整此行為。
- 交付語(yǔ)義-NATS支持最多一次(At most once)(并且NATS流至少支持一次),而Kafka則支持僅一次(Exactly once)( NATs似乎沒(méi)有像Kafka那樣對(duì)分區(qū)/分片消息的概念,在NATS情況下沒(méi)有外部依賴性。 Kafka要求Zookeeper,NATS Streaming似乎與Kafka功能集相似,但是使用Go構(gòu)建并且看起來(lái)更易于設(shè)置. NATS目前不支持復(fù)制(或?qū)嶋H上沒(méi)有任何高可用性設(shè)置)。與Kafka相比,這是一個(gè)主要的缺失功能。
#NSQ:
易于設(shè)置NSQ似乎更靈活,它支持消息持久性,并且在持久性要求不高的情況下,還提供類似于NATS的臨時(shí)通道。 它配備了NATS缺少的閃亮的管理儀表板。 當(dāng)優(yōu)先考慮原始性能時(shí),NATS很有用.NATS和NSQ隊(duì)列均支持按消息TTL,以修剪時(shí)間敏感消息。
Kafka很復(fù)雜,但保證不會(huì)丟失任何數(shù)據(jù)。 適合訂購(gòu)日志。 NSQ缺乏持久性和復(fù)制能力。 大規(guī)模操作非常簡(jiǎn)單。Kafka的性能和增強(qiáng)的保證以難以操作為代價(jià)。有了Kafka,除了Kafka經(jīng)紀(jì)人,您還需要一個(gè)Zookeeper集群。 Kafka需要考慮分區(qū)和偏移量,最好將Kafka視為分布式日志服務(wù),而不是消息傳遞代理,例如數(shù)據(jù)庫(kù)中的預(yù)寫(xiě)日志而不是printf語(yǔ)句。
NSQ是一種更為傳統(tǒng)的緩沖消息系統(tǒng)。 它具有文件持久性,但僅作為 a)優(yōu)化以防止一旦內(nèi)存用完就會(huì)丟失消息,以及b)作為使用者檔案。 但是,節(jié)點(diǎn)的嚴(yán)重丟失意味著尚未傳遞的那些消息可能會(huì)丟失,因?yàn)闊o(wú)法保證它們會(huì)在其他地方發(fā)布。 此外,不能保證發(fā)布到主題和頻道的消息順序是消費(fèi)者接收到的消息順序。 使用NSQ,有一個(gè)內(nèi)置實(shí)用程序nsq_to_file,它成為您將每個(gè)消息主題歸檔到磁盤時(shí)的另一個(gè)使用方。 它提供了簡(jiǎn)單的郵件存檔功能,但不提供任何本地重播功能。
#Apache Pulsar(pulsar.incubator.apache.org):
基于Java
它是雅虎公司設(shè)計(jì)的,是一種高性能,低延遲,可擴(kuò)展的持久解決方案,用于發(fā)布訂閱消息和消息排隊(duì)。 Apache Pulsar將高性能流(Apache Kafka追求)和靈活的傳統(tǒng)排隊(duì)(RabbitMQ追求)結(jié)合在一起,成為統(tǒng)一的消息傳遞模型和API。 Pulsar使用統(tǒng)一的API為您提供具有相同高性能的流和排隊(duì)系統(tǒng)。 總而言之,Kafka的目標(biāo)是高吞吐量,Pulsar的目標(biāo)是低延遲。
Pulsar 優(yōu)點(diǎn)
- 豐富—持久性/非持久性主題,多租戶,ACL,多DC復(fù)制等。
- 更易于使用的更靈活的客戶端API(包括CompletableFutures,流暢的接口等)。
- Java客戶端組件是線程安全的,消費(fèi)者可以確認(rèn)來(lái)自不同的線程的消息
Pulsar 缺點(diǎn)
- Java客戶端幾乎沒(méi)有Javadoc
- Small社區(qū)-當(dāng)前有8個(gè)stackoverflow問(wèn)題
- 與BookKeeper綁定的MessageId
- 與連續(xù)數(shù)字序列的Kafka偏移量相比,消費(fèi)者無(wú)法輕松地將自己定位在主題上。讀者無(wú)法輕松閱讀關(guān)于該主題的最后一條消息。
- 沒(méi)有事務(wù)支持。
- 更高的操作復(fù)雜性— Zookeeper + Broker節(jié)點(diǎn)+ BookKeeper —所有clusterLatency都可疑— Broker節(jié)點(diǎn)與BookKeeper之間有一個(gè)額外的遠(yuǎn)程調(diào)用(與Kafka相比)
Kafka 優(yōu)點(diǎn)
- 非常豐富和有用的JavaDoc
- Kafka Streams 成熟和廣泛的社區(qū)
- 在生產(chǎn)中易于操作-更少的組件-代理節(jié)點(diǎn)還提供storage
- 事務(wù)-主題內(nèi)的原子讀取和寫(xiě)入偏移形成連續(xù)序列-消費(fèi)者可以輕松地尋找到最后一條消息
Kafka 缺點(diǎn)
- Consumer無(wú)法確認(rèn)來(lái)自其他線程的消息
- 沒(méi)有多租戶
- 沒(méi)有健壯的Multi-DC復(fù)制-(在Confluent Enterprise中提供)
- 在云環(huán)境中的管理很困難。