高并發(fā)架構(gòu)系列:Kafka、RocketMQ、RabbitMQ的優(yōu)劣勢比較

在高并發(fā)業(yè)務(wù)場景下,典型的阿里雙11秒殺等業(yè)務(wù),消息隊(duì)列中間件在流量削峰、解耦上有不可替代的作用。

之前介紹了《MQ消息隊(duì)列的12點(diǎn)核心原理總結(jié)》,以及《如何從0到1設(shè)計一個MQ消息隊(duì)列》,以及《RPC遠(yuǎn)程調(diào)用和消息隊(duì)列MQ的區(qū)別》。

今天我們一起來探討:

全量的消息隊(duì)列究竟有哪些? Kafka、RocketMQ、RabbitMQ的優(yōu)劣勢比較,以及消息隊(duì)列的選型

最全MQ消息隊(duì)列有哪些?

那么目前在業(yè)界有哪些比較知名的消息引擎呢?如下圖所示

這里面幾乎完全列舉了當(dāng)下比較知名的消息引擎,包括:

ZeroMQ

推特的Distributedlog

ActiveMQ:Apache旗下的老牌消息引擎

RabbitMQ、Kafka:AMQP的默認(rèn)實(shí)現(xiàn)。

RocketMQ

Artemis:Apache的ActiveMQ下的子項(xiàng)目

Apollo:同樣為Apache的ActiveMQ的子項(xiàng)目的號稱下一代消息引擎

商業(yè)化的消息引擎IronMQ

以及實(shí)現(xiàn)了JMS(Java Message Service)標(biāo)準(zhǔn)的OpenMQ。

MQ消息隊(duì)列的技術(shù)應(yīng)用

1.解耦

解耦是消息隊(duì)列要解決的最本質(zhì)問題。

2.最終一致性

最終一致性指的是兩個系統(tǒng)的狀態(tài)保持一致,要么都成功,要么都失敗。

最終一致性不是消息隊(duì)列的必備特性,但確實(shí)可以依靠消息隊(duì)列來做最終一致性的事情。

2.廣播

消息隊(duì)列的基本功能之一是進(jìn)行廣播。

有了消息隊(duì)列,我們只需要關(guān)心消息是否送達(dá)了隊(duì)列,至于誰希望訂閱,是下游的事情,無疑極大地減少了開發(fā)和聯(lián)調(diào)的工作量。

3.錯峰與流控

典型的使用場景就是秒殺業(yè)務(wù)用于流量削峰場景。

由于篇幅的關(guān)系,本文重點(diǎn)介紹消息隊(duì)列比較,詳細(xì)應(yīng)用場景請參考:《什么是流量削峰?如何解決秒殺業(yè)務(wù)的削峰場景》。

Kafka、RocketMQ、RabbitMQ比較

1.ActiveMQ

優(yōu)點(diǎn)

單機(jī)吞吐量:萬級

topic數(shù)量都吞吐量的影響:

時效性:ms級

可用性:高,基于主從架構(gòu)實(shí)現(xiàn)高可用性

消息可靠性:有較低的概率丟失數(shù)據(jù)

功能支持:MQ領(lǐng)域的功能極其完備

缺點(diǎn):

官方社區(qū)現(xiàn)在對ActiveMQ 5.x維護(hù)越來越少,較少在大規(guī)模吞吐的場景中使用。

2.Kafka

號稱大數(shù)據(jù)的殺手锏,談到大數(shù)據(jù)領(lǐng)域內(nèi)的消息傳輸,則繞不開Kafka,這款為大數(shù)據(jù)而生的消息中間件,以其百萬級TPS的吞吐量名聲大噪,迅速成為大數(shù)據(jù)領(lǐng)域的寵兒,在數(shù)據(jù)采集、傳輸、存儲的過程中發(fā)揮著舉足輕重的作用。

Apache Kafka它最初由LinkedIn公司基于獨(dú)特的設(shè)計實(shí)現(xiàn)為一個分布式的提交日志系統(tǒng)( a distributed commit log),之后成為Apache項(xiàng)目的一部分。

目前已經(jīng)被LinkedIn,Uber, Twitter, Netflix等大公司所采納。

優(yōu)點(diǎn)

性能卓越,單機(jī)寫入TPS約在百萬條/秒,最大的優(yōu)點(diǎn),就是吞吐量高。

時效性:ms級

可用性:非常高,kafka是分布式的,一個數(shù)據(jù)多個副本,少數(shù)機(jī)器宕機(jī),不會丟失數(shù)據(jù),不會導(dǎo)致不可用

消費(fèi)者采用Pull方式獲取消息, 消息有序, 通過控制能夠保證所有消息被消費(fèi)且僅被消費(fèi)一次;

有優(yōu)秀的第三方Kafka Web管理界面Kafka-Manager;

在日志領(lǐng)域比較成熟,被多家公司和多個開源項(xiàng)目使用;

功能支持:功能較為簡單,主要支持簡單的MQ功能,在大數(shù)據(jù)領(lǐng)域的實(shí)時計算以及日志采集被大規(guī)模使用

缺點(diǎn):

Kafka單機(jī)超過64個隊(duì)列/分區(qū),Load會發(fā)生明顯的飆高現(xiàn)象,隊(duì)列越多,load越高,發(fā)送消息響應(yīng)時間變長

使用短輪詢方式,實(shí)時性取決于輪詢間隔時間;

消費(fèi)失敗不支持重試;

支持消息順序,但是一臺代理宕機(jī)后,就會產(chǎn)生消息亂序;

社區(qū)更新較慢;

3.RabbitMQ

RabbitMQ 2007年發(fā)布,是一個在AMQP(高級消息隊(duì)列協(xié)議)基礎(chǔ)上完成的,可復(fù)用的企業(yè)消息系統(tǒng),是當(dāng)前最主流的消息中間件之一。

RabbitMQ優(yōu)點(diǎn)

由于erlang語言的特性,mq 性能較好,高并發(fā);

吞吐量到萬級,MQ功能比較完備

健壯、穩(wěn)定、易用、跨平臺、支持多種語言、文檔齊全;

開源提供的管理界面非常棒,用起來很好用

社區(qū)活躍度高;

RabbitMQ缺點(diǎn):

erlang開發(fā),很難去看懂源碼,基本職能依賴于開源社區(qū)的快速維護(hù)和修復(fù)bug,不利于做二次開發(fā)和維護(hù)。

RabbitMQ確實(shí)吞吐量會低一些,這是因?yàn)樗龅膶?shí)現(xiàn)機(jī)制比較重。

需要學(xué)習(xí)比較復(fù)雜的接口和協(xié)議,學(xué)習(xí)和維護(hù)成本較高。

4.RocketMQ

RocketMQ出自 阿里公司的開源產(chǎn)品,用 Java 語言實(shí)現(xiàn),在設(shè)計時參考了 Kafka,并做出了自己的一些改進(jìn)。

RocketMQ在阿里集團(tuán)被廣泛應(yīng)用在訂單,交易,充值,流計算,消息推送,日志流式處理,binglog分發(fā)等場景。

RocketMQ優(yōu)點(diǎn):

單機(jī)吞吐量:十萬級

可用性:非常高,分布式架構(gòu)

消息可靠性:經(jīng)過參數(shù)優(yōu)化配置,消息可以做到0丟失

功能支持:MQ功能較為完善,還是分布式的,擴(kuò)展性好

支持10億級別的消息堆積,不會因?yàn)槎逊e導(dǎo)致性能下降

源碼是java,我們可以自己閱讀源碼,定制自己公司的MQ,可以掌控

RocketMQ缺點(diǎn):

支持的客戶端語言不多,目前是java及c++,其中c++不成熟;

社區(qū)活躍度一般

沒有在 mq 核心中去實(shí)現(xiàn)JMS等接口,有些系統(tǒng)要遷移需要修改大量代碼

消息隊(duì)列選擇建議

1.Kafka

Kafka主要特點(diǎn)是基于Pull的模式來處理消息消費(fèi),追求高吞吐量,一開始的目的就是用于日志收集和傳輸,適合產(chǎn)生大量數(shù)據(jù)的互聯(lián)網(wǎng)服務(wù)的數(shù)據(jù)收集業(yè)務(wù)。

大型公司建議可以選用,如果有日志采集功能,肯定是首選kafka了。

2.RocketMQ

天生為金融互聯(lián)網(wǎng)領(lǐng)域而生,對于可靠性要求很高的場景,尤其是電商里面的訂單扣款,以及業(yè)務(wù)削峰,在大量交易涌入時,后端可能無法及時處理的情況。

RoketMQ在穩(wěn)定性上可能更值得信賴,這些業(yè)務(wù)場景在阿里雙11已經(jīng)經(jīng)歷了多次考驗(yàn),如果你的業(yè)務(wù)有上述并發(fā)場景,建議可以選擇RocketMQ。

3.RabbitMQ

RabbitMQ :結(jié)合erlang語言本身的并發(fā)優(yōu)勢,性能較好,社區(qū)活躍度也比較高,但是不利于做二次開發(fā)和維護(hù)。不過,RabbitMQ的社區(qū)十分活躍,可以解決開發(fā)過程中遇到的bug。

如果你的數(shù)據(jù)量沒有那么大,小公司優(yōu)先選擇功能比較完備的RabbitMQ。

作者:MikeChen架構(gòu)筆記
鏈接:http://www.itdecent.cn/p/fec054f3e496
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

補(bǔ)充

1.1 特性
RocketMQ:

NameServer:整個MQ集群提供服務(wù)協(xié)調(diào)與治理,具體就是記錄維護(hù)Topic、Broker的信息,及監(jiān)控Broker的運(yùn)行狀態(tài),Name Server是一個幾乎無狀態(tài)節(jié)點(diǎn),可集群部署,節(jié)點(diǎn)之間無任何信息同步,相當(dāng)于注冊中心.
Broker:消息服務(wù)器,作為server提供消息核心服務(wù),每個Broker與Name Server集群中的所有節(jié)點(diǎn)建立長連接,定時注冊Topic信息到所有Name Server;
Producer:消息生產(chǎn)者,業(yè)務(wù)的發(fā)起方,負(fù)責(zé)生產(chǎn)消息傳輸給broker.
Consumer:消息消費(fèi)者,業(yè)務(wù)的處理方,負(fù)責(zé)從broker獲取消息并進(jìn)行業(yè)務(wù)邏輯處理
RabbitMQ:

Exchange:交換機(jī)的作用就是根據(jù)路由規(guī)則,將消息轉(zhuǎn)發(fā)到對應(yīng)的隊(duì)列上。.
Broker:消息服務(wù)器,作為server提供消息核心服務(wù)
Channel:信道是建立在真實(shí)的TCP連接內(nèi)的虛擬連接.
Routing key:生產(chǎn)者將消息發(fā)送到交換機(jī)時,會在消息頭上攜帶一個 key,這個 key就是routing key,來指定這個消息的路由規(guī)則。
Binding key:在綁定Exchange與Queue時,一般會指定一個binding key,生產(chǎn)者將消息發(fā)送給Exchange時,消息頭上會攜帶一個routing key,當(dāng)binding key與routing key相匹配時,消息將會被路由到對應(yīng)的Queue中。
1.2 重復(fù)消費(fèi)
正常情況下,消費(fèi)者在消費(fèi)消息的時候,消費(fèi)完畢后,會發(fā)送一個確認(rèn)消息給消息隊(duì)列,消息隊(duì)列就知道該消息被消費(fèi)了,就會將該消息從消息隊(duì)列中刪除; 但是因?yàn)榫W(wǎng)絡(luò)傳輸?shù)鹊裙收?,確認(rèn)信息沒有傳送到消息隊(duì)列,導(dǎo)致消息隊(duì)列不知道自己已經(jīng)消費(fèi)過該消息了,再次將消息分發(fā)給其他的消費(fèi)者。

保證消息的唯一性,就算是多次傳輸,不要讓消息的多次消費(fèi)帶來影響;保證消息等冪性;

1.3 丟失數(shù)據(jù)
RocketMQ:

生產(chǎn)者丟數(shù)據(jù):(1)采取send()同步發(fā)消息,發(fā)送結(jié)果是同步感知的。發(fā)送失敗后可以重試,設(shè)置重試次數(shù)。默認(rèn)3次。(2)發(fā)送失敗的消息會存儲在Commitlog中。
消息隊(duì)列丟數(shù)據(jù):(1)消息支持持久化到Commitlog里面,即使宕機(jī)后重啟,未消費(fèi)的消息也是可以加載出來的;(2)Broker自身支持同步刷盤、異步刷盤的策略,可以保證接收到的消息一定存儲在本地的內(nèi)存中;(3)Broker集群支持 1主N從的策略,支持同步復(fù)制和異步復(fù)制的方式,同步復(fù)制可以保證即使Master 磁盤崩潰,消息仍然不會丟失
消費(fèi)者丟失數(shù)據(jù):(1)完全成功后發(fā)送ACK;(2)維護(hù)一個持久化的offset
RabbitMQ:

生產(chǎn)者丟數(shù)據(jù):RabbitMQ提供transaction(事務(wù),支持回滾)和confirm模式(ACK給生產(chǎn)者)來確保生產(chǎn)者不丟消息;
消息隊(duì)列丟數(shù)據(jù):開啟rabbitmq的持久化,就是消息寫入之后會持久化到磁盤,持久化可以跟生產(chǎn)者那邊的confirm機(jī)制配合起來,只有消息被持久化到磁盤之后,才會通知生產(chǎn)者ack。
消費(fèi)者丟失數(shù)據(jù):消費(fèi)者丟數(shù)據(jù)一般是因?yàn)椴捎昧俗詣哟_認(rèn)消息模式,改為手動確認(rèn)消息,處理消息成功后,手動回復(fù)確認(rèn)消息。
1.4 消費(fèi)順序
主要思路有兩種:1、單線程消費(fèi)來保證消息的順序性;2、對消息進(jìn)行編號,消費(fèi)者處理時根據(jù)編號判斷順序。

每個queue的數(shù)據(jù)本身就是有序的,只要消費(fèi)者這邊有序消費(fèi),那么可以保證數(shù)據(jù)被順序消費(fèi)。如果是多線程消費(fèi),就要consumer內(nèi)部用內(nèi)存隊(duì)列做排隊(duì)。

1.5 高可用
RocketMQ:

多Master:配置簡單,性能最高,但可能會有少量消息丟失(配置相關(guān)),單臺機(jī)器重啟或宕機(jī)期間,該機(jī)器下未被消費(fèi)的消息在機(jī)器恢復(fù)前不可訂閱,影響消息實(shí)時性
多Master多Slave異步模式:每個Master配一個Slave,有多對Master-Slave,消息寫入全部是發(fā)送到Master Broker的,獲取消息也可以Master獲取,少了Slave Broker,會導(dǎo)致所有讀寫壓力都集中在Master Broker,集群采用異步復(fù)制方式,主備有短暫消息延遲,毫秒級;性能同多Master幾乎一樣,實(shí)時性高,主備間切換對應(yīng)用透明,不需人工干預(yù),但Master宕機(jī)或磁盤損壞時會有少量消息丟失;
多Master多Slave同步模式:每個Master配一個Slave,有多對Master-Slave,消息寫入全部是發(fā)送到Master Broker的,獲取消息也可以Master獲取,少了Slave Broker,會導(dǎo)致所有讀寫壓力都集中在Master Broker,集群采用同步雙寫方式,主備都寫成功,向應(yīng)用返回成功;優(yōu)點(diǎn)是服務(wù)可用性與數(shù)據(jù)可用性非常高;缺點(diǎn)是性能比異步集群略低,當(dāng)前版本主宕備不能自動切換為主。
RabbitMQ:

普通集群模式:多臺機(jī)器上啟動多個rabbitmq實(shí)例,每個機(jī)器啟動一個。但是你創(chuàng)建的queue,只會放在一個rabbtimq實(shí)例上,但是每個實(shí)例都同步queue的元數(shù)據(jù)。完了你消費(fèi)的時候,實(shí)際上如果連接到了另外一個實(shí)例,那么那個實(shí)例會從queue所在實(shí)例上拉取數(shù)據(jù)過來。如果那個放queue的實(shí)例宕機(jī)了,會導(dǎo)致接下來其他實(shí)例就無法從那個實(shí)例拉取,如果你開啟了消息持久化,讓rabbitmq落地存儲消息的話,消息不一定會丟,得等這個實(shí)例恢復(fù)了,然后才可以繼續(xù)從這個queue拉取數(shù)據(jù)。
鏡像集群模式:創(chuàng)建的queue,無論元數(shù)據(jù)還是queue里的消息都會存在于多個實(shí)例上,然后每次寫消息到queue的時候,都會自動把消息到多個實(shí)例的queue里進(jìn)行消息同步。缺點(diǎn):(1)性能開銷大,因?yàn)樾枰M(jìn)行整個集群內(nèi)部所有實(shí)例的數(shù)據(jù)同步;(2)無法線性擴(kuò)容: 因?yàn)槊恳粋€服務(wù)器中都包含整個集群服務(wù)節(jié)點(diǎn)中的所有數(shù)據(jù), 這樣如果一旦單個服務(wù)器節(jié)點(diǎn)的容量無法容納了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容