17 個(gè)方面,綜合對(duì)比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四個(gè)分布式消息隊(duì)列
本文將從,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 個(gè)方面綜合比照作為音訊行列運(yùn)用時(shí)的差異。
良心引薦:如下 10 篇文章,是艿艿寫的四種 MQ 在 Spring Boot、Spring Cloud 的實(shí)戰(zhàn)文章~~~
良心引薦:如下 10 篇文章,是艿艿寫的四種 MQ 在 Spring Boot、Spring Cloud 的實(shí)戰(zhàn)文章~~~
一、材料文檔
Kafka:中。有kafka作者自己寫的書,網(wǎng)上材料也有一些。rabbitmq:多。有一些不錯(cuò)的書,網(wǎng)上材料多。zeromq:少。沒有專門寫zeromq的書,網(wǎng)上的材料多是一些代碼的完成和簡(jiǎn)略介紹。rocketmq:少。沒有專門寫rocketmq的書,網(wǎng)上的材料良莠不齊,官方文檔很簡(jiǎn)潔,可是對(duì)技能細(xì)節(jié)沒有過多的描繪。activemq:多。沒有專門寫activemq的書,網(wǎng)上材料多。
二、開發(fā)言語
Kafka:Scala rabbitmq:Erlang zeromq:c rocketmq:java activemq:java
三、支撐的協(xié)議
Kafka:自己界說的一套...(依據(jù)TCP) rabbitmq:AMQP zeromq:TCP、UDP rocketmq:自己界說的一套... activemq:OpenWire、STOMP、REST、XMPP、AMQP
四、音訊存儲(chǔ)
Kafka:內(nèi)存、磁盤、數(shù)據(jù)庫(kù)。支撐許多堆積。
kafka的最小存儲(chǔ)單元是分區(qū),一個(gè)topic包括多個(gè)分區(qū),kafka創(chuàng)立主題時(shí),這些分區(qū)會(huì)被分配在多個(gè)服務(wù)器上,一般一個(gè)broker一臺(tái)服務(wù)器。分區(qū)首體會(huì)均勻地散布在不同的服務(wù)器上,分區(qū)副本也會(huì)均勻的散布在不同的服務(wù)器上,確保負(fù)載均衡和高可用性,當(dāng)新的broker參加集群的時(shí)分,部分副本會(huì)被移動(dòng)到新的broker上。依據(jù)裝備文件中的目錄清單,kafka會(huì)把新的分區(qū)分配給目錄清單里分區(qū)數(shù)最少的目錄。默認(rèn)狀況下,分區(qū)器運(yùn)用輪詢算法把音訊均衡地散布在同一個(gè)主題的不同分區(qū)中,關(guān)于發(fā)送時(shí)指定了key的狀況,會(huì)依據(jù)key的hashcode取模后的值存到對(duì)應(yīng)的分區(qū)中。
rabbitmq:內(nèi)存、磁盤。支撐少量堆積。
rabbitmq的音訊分為耐久化的音訊和非耐久化音訊,不管是耐久化的音訊還是非耐久化的音訊都能夠?qū)懭氲酱疟P。耐久化的音訊在到達(dá)行列時(shí)就寫入到磁盤,并且假如能夠,耐久化的音訊也會(huì)在內(nèi)存中保存一份備份,這樣能夠進(jìn)步必定的功能,當(dāng)內(nèi)存吃緊的時(shí)分會(huì)從內(nèi)存中清除。非耐久化的音訊一般只存在于內(nèi)存中,在內(nèi)存吃緊的時(shí)分會(huì)被換入到磁盤中,以節(jié)省內(nèi)存。
引進(jìn)鏡像行列機(jī)制,可將重要行列“仿制”到集群中的其他broker上,確保這些行列的音訊不會(huì)丟掉。裝備鏡像的行列,都包括一個(gè)主節(jié)點(diǎn)master和多個(gè)從節(jié)點(diǎn)slave,假如master失效,參加時(shí)刻最長(zhǎng)的slave會(huì)被提升為新的master,除發(fā)送音訊外的一切動(dòng)作都向master發(fā)送,然后由master將指令履行結(jié)果播送給各個(gè)slave,rabbitmq會(huì)讓master均勻地散布在不同的服務(wù)器上,而同一個(gè)行列的slave也會(huì)均勻地散布在不同的服務(wù)器上,確保負(fù)載均衡和高可用性。
zeromq:音訊發(fā)送端的內(nèi)存或許磁盤中。不支撐耐久化。
rocketmq:磁盤。支撐許多堆積。
commitLog文件寄存實(shí)際的音訊數(shù)據(jù),每個(gè)commitLog上限是1G,滿了之后會(huì)主動(dòng)新建一個(gè)commitLog文件保存數(shù)據(jù)。ConsumeQueue行列只寄存offset、size、tagcode,十分小,散布在多個(gè)broker上。ConsumeQueue相當(dāng)于CommitLog的索引文件,顧客消費(fèi)時(shí)會(huì)從consumeQueue中查找音訊在commitLog中的offset,再去commitLog中查找元數(shù)據(jù)。
ConsumeQueue存儲(chǔ)格式的特性,確保了寫過程的次序?qū)懕P(寫CommitLog文件),許多數(shù)據(jù)IO都在次序?qū)懲粋€(gè)commitLog,滿1G了再寫新的。加上rocketmq是累計(jì)4K才強(qiáng)制從PageCache中刷到磁盤(緩存),所以高并發(fā)寫功能突出。
activemq:內(nèi)存、磁盤、數(shù)據(jù)庫(kù)。支撐少量堆積。
五、音訊事務(wù)
Kafka:支撐 rabbitmq:支撐。客戶端將信道設(shè)置為事務(wù)辦法,只要當(dāng)音訊被rabbitMq接納,事務(wù)才能提交成功,否則在捕獲異常后進(jìn)行回滾。運(yùn)用事務(wù)會(huì)使得功能有所下降 zeromq:不支撐 rocketmq:支撐 activemq:支撐
六、負(fù)載均衡
Kafka:支撐負(fù)載均衡。
1>一個(gè)broker一般就是一臺(tái)服務(wù)器節(jié)點(diǎn)。關(guān)于同一個(gè)Topic的不同分區(qū),Kafka會(huì)極力將這些分區(qū)散布到不同的Broker服務(wù)器上,zookeeper保存了broker、主題和分區(qū)的元數(shù)據(jù)信息。分區(qū)首體會(huì)處理來自客戶端的出產(chǎn)懇求,kafka分區(qū)首體會(huì)被分配到不同的broker服務(wù)器上,讓不同的broker服務(wù)器一起分管使命。
每一個(gè)broker都緩存了元數(shù)據(jù)信息,客戶端能夠從恣意一個(gè)broker獲取元數(shù)據(jù)信息并緩存起來,依據(jù)元數(shù)據(jù)信息知道要往哪里發(fā)送懇求。
2>kafka的顧客組訂閱同一個(gè)topic,會(huì)盡或許地使得每一個(gè)顧客分配到相同數(shù)量的分區(qū),分?jǐn)傌?fù)載。
3>當(dāng)顧客參加或許退出顧客組的時(shí)分,還會(huì)觸發(fā)再均衡,為每一個(gè)顧客重新分配分區(qū),分?jǐn)傌?fù)載。
kafka的負(fù)載均衡大部分是主動(dòng)完成的,分區(qū)的創(chuàng)立也是kafka完成的,躲藏了許多細(xì)節(jié),避免了繁瑣的裝備和人為忽略構(gòu)成的負(fù)載問題。
4>發(fā)送端由topic和key來決議音訊發(fā)往哪個(gè)分區(qū),假如key為null,那么會(huì)運(yùn)用輪詢算法將音訊均衡地發(fā)送到同一個(gè)topic的不同分區(qū)中。假如key不為null,那么會(huì)依據(jù)key的hashcode取模計(jì)算出要發(fā)往的分區(qū)。
rabbitmq:對(duì)負(fù)載均衡的支撐欠好。
1>音訊被投遞到哪個(gè)行列是由交換器和key決議的,交換器、路由鍵、行列都需求手動(dòng)創(chuàng)立。
rabbitmq客戶端發(fā)送音訊要和broker樹立銜接,需求事先知道broker上有哪些交換器,有哪些行列。一般要聲明要發(fā)送的方針行列,假如沒有方針行列,會(huì)在broker上創(chuàng)立一個(gè)行列,假如有,就什么都不處理,接著往這個(gè)行列發(fā)送音訊。假設(shè)大部分深重使命的行列都創(chuàng)立在同一個(gè)broker上,那么這個(gè)broker的負(fù)載就會(huì)過大。(能夠在上線前預(yù)先創(chuàng)立行列,無需聲明要發(fā)送的行列,可是發(fā)送時(shí)不會(huì)嘗試創(chuàng)立行列,或許呈現(xiàn)找不到行列的問題,rabbitmq的備份交換器會(huì)把找不到行列的音訊保存到一個(gè)專門的行列中,以便以后查詢運(yùn)用)
運(yùn)用鏡像行列機(jī)制樹立rabbitmq集群能夠處理這個(gè)問題,構(gòu)成master-slave的架構(gòu),master節(jié)點(diǎn)會(huì)均勻散布在不同的服務(wù)器上,讓每一臺(tái)服務(wù)器分?jǐn)傌?fù)載。slave節(jié)點(diǎn)僅僅負(fù)責(zé)轉(zhuǎn)發(fā),在master失效時(shí)會(huì)選擇參加時(shí)刻最長(zhǎng)的slave成為master。
當(dāng)新節(jié)點(diǎn)參加鏡像行列的時(shí)分,行列中的音訊不會(huì)同步到新的slave中,除非調(diào)用同步指令,可是調(diào)用指令后,行列會(huì)阻塞,不能在出產(chǎn)環(huán)境中調(diào)用同步指令。
2>當(dāng)rabbitmq行列具有多個(gè)顧客的時(shí)分,行列收到的音訊將以輪詢的分發(fā)辦法發(fā)送給顧客。每條音訊只會(huì)發(fā)送給訂閱列表里的一個(gè)顧客,不會(huì)重復(fù)。
這種辦法十分合適擴(kuò)展,并且是專門為并發(fā)程序設(shè)計(jì)的。
假如某些顧客的使命比較深重,那么能夠設(shè)置basicQos約束信道上顧客能堅(jiān)持的最大未承認(rèn)音訊的數(shù)量,在到達(dá)上限時(shí),rabbitmq不再向這個(gè)顧客發(fā)送任何音訊。
3>關(guān)于rabbitmq而言,客戶端與集群樹立的TCP銜接不是與集群中一切的節(jié)點(diǎn)樹立銜接,而是挑選其間一個(gè)節(jié)點(diǎn)樹立銜接。
可是rabbitmq集群能夠借助HAProxy、LVS技能,或許在客戶端運(yùn)用算法完成負(fù)載均衡,引進(jìn)負(fù)載均衡之后,各個(gè)客戶端的銜接能夠分?jǐn)偟郊旱母鱾€(gè)節(jié)點(diǎn)之中。
客戶端均衡算法:
1)輪詢法。按次序回來下一個(gè)服務(wù)器的銜接地址。
2)加權(quán)輪詢法。給裝備高、負(fù)載低的機(jī)器裝備更高的權(quán)重,讓其處理更多的懇求;而裝備低、負(fù)載高的機(jī)器,給其分配較低的權(quán)重,降低其體系負(fù)載。
3)隨機(jī)法。隨機(jī)選取一個(gè)服務(wù)器的銜接地址。
4)加權(quán)隨機(jī)法。依照概率隨機(jī)選取銜接地址。
5)源地址哈希法。經(jīng)過哈希函數(shù)計(jì)算得到的一個(gè)數(shù)值,用該數(shù)值對(duì)服務(wù)器列表的巨細(xì)進(jìn)行取模運(yùn)算。
6)最小銜接數(shù)法。動(dòng)態(tài)選擇當(dāng)時(shí)銜接數(shù)最少的一臺(tái)服務(wù)器的銜接地址。
zeromq:去中心化,不支撐負(fù)載均衡。自身僅僅一個(gè)多線程網(wǎng)絡(luò)庫(kù)。
rocketmq:支撐負(fù)載均衡。
一個(gè)broker一般是一個(gè)服務(wù)器節(jié)點(diǎn),broker分為master和slave,master和slave存儲(chǔ)的數(shù)據(jù)相同,slave從master同步數(shù)據(jù)。
1>nameserver與每個(gè)集群成員堅(jiān)持心跳,保存著Topic-Broker路由信息,同一個(gè)topic的行列會(huì)散布在不同的服務(wù)器上。
2>發(fā)送音訊經(jīng)過輪詢行列的辦法發(fā)送,每個(gè)行列接納均勻的音訊量。發(fā)送音訊指定topic、tags、keys,無法指定投遞到哪個(gè)行列(沒有意義,集群消費(fèi)和播送消費(fèi)跟音訊寄存在哪個(gè)行列沒有關(guān)系)。
tags選填,類似于 Gmail 為每封郵件設(shè)置的標(biāo)簽,方便服務(wù)器過濾運(yùn)用?,F(xiàn)在只支 持每個(gè)音訊設(shè)置一個(gè) tag,所以也能夠類比為 Notify 的 MessageType 概念。
keys選填,代表這條音訊的事務(wù)關(guān)鍵詞,服務(wù)器會(huì)依據(jù) keys 創(chuàng)立哈希索引,設(shè)置后, 能夠在 Console 體系依據(jù) Topic、Keys 來查詢音訊,因?yàn)槭枪K饕?,?qǐng)盡或許 確保 key 僅有,例如訂單號(hào),產(chǎn)品 Id 等。
3>rocketmq的負(fù)載均衡戰(zhàn)略規(guī)定:Consumer數(shù)量應(yīng)該小于等于Queue數(shù)量,假如Consumer超越Queue數(shù)量,那么剩余的Consumer 將不能消費(fèi)音訊。這一點(diǎn)和kafka是共同的,rocketmq會(huì)盡或許地為每一個(gè)Consumer分配相同數(shù)量的行列,分?jǐn)傌?fù)載。
activemq:支撐負(fù)載均衡。能夠依據(jù)zookeeper完成負(fù)載均衡。
七、集群辦法
Kafka:天然的‘Leader-Slave’無狀況集群,每臺(tái)服務(wù)器既是Master也是Slave。
分區(qū)領(lǐng)袖均勻地散布在不同的kafka服務(wù)器上,分區(qū)副本也均勻地散布在不同的kafka服務(wù)器上,所以每一臺(tái)kafka服務(wù)器既含有分區(qū)領(lǐng)袖,一起又含有分區(qū)副本,每一臺(tái)kafka服務(wù)器是某一臺(tái)kafka服務(wù)器的Slave,一起也是某一臺(tái)kafka服務(wù)器的leader。
kafka的集群依賴于zookeeper,zookeeper支撐熱擴(kuò)展,一切的broker、顧客、分區(qū)都能夠動(dòng)態(tài)參加移除,而無需封閉服務(wù),與不依托zookeeper集群的mq比較,這是最大的優(yōu)勢(shì)。
rabbitmq:支撐簡(jiǎn)略集群,'仿制'辦法,對(duì)高檔集群辦法支撐欠好。
rabbitmq的每一個(gè)節(jié)點(diǎn),不管是單一節(jié)點(diǎn)體系或許是集群中的一部分,要么是內(nèi)存節(jié)點(diǎn),要么是磁盤節(jié)點(diǎn),集群中至少要有一個(gè)是磁盤節(jié)點(diǎn)。
在rabbitmq集群中創(chuàng)立行列,集群只會(huì)在單個(gè)節(jié)點(diǎn)創(chuàng)立行列進(jìn)程和完好的行列信息(元數(shù)據(jù)、狀況、內(nèi)容),而不是在一切節(jié)點(diǎn)上創(chuàng)立。
引進(jìn)鏡像行列,能夠避免單點(diǎn)故障,確保服務(wù)的可用性,可是需求人為地為某些重要的行列裝備鏡像。
zeromq:去中心化,不支撐集群。
rocketmq:常用 多對(duì)'Master-Slave' 辦法,開源版別需手動(dòng)切換Slave變成Master
Name Server是一個(gè)簡(jiǎn)直無狀況節(jié)點(diǎn),可集群布置,節(jié)點(diǎn)之間無任何信息同步。
Broker布置相對(duì)雜亂,Broker分為Master與Slave,一個(gè)Master能夠?qū)?yīng)多個(gè)Slave,可是一個(gè)Slave只能對(duì)應(yīng)一個(gè)Master,Master與Slave的對(duì)應(yīng)關(guān)系經(jīng)過指定相同的BrokerName,不同的BrokerId來界說,BrokerId為0表示Master,非0表示Slave。Master也能夠布置多個(gè)。每個(gè)Broker與Name Server集群中的一切節(jié)點(diǎn)樹立長(zhǎng)銜接,守時(shí)注冊(cè)Topic信息到一切Name Server。
Producer與Name Server集群中的其間一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)樹立長(zhǎng)銜接,守時(shí)從Name Server取Topic路由信息,并向供給Topic服務(wù)的Master樹立長(zhǎng)銜接,且守時(shí)向Master發(fā)送心跳。Producer徹底無狀況,可集群布置。
Consumer與Name Server集群中的其間一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)樹立長(zhǎng)銜接,守時(shí)從Name Server取Topic路由信息,并向供給Topic服務(wù)的Master、Slave樹立長(zhǎng)銜接,且守時(shí)向Master、Slave發(fā)送心跳。Consumer既能夠從Master訂閱音訊,也能夠從Slave訂閱音訊,訂閱規(guī)則由Broker裝備決議。
客戶端先找到NameServer, 然后經(jīng)過NameServer再找到 Broker。
一個(gè)topic有多個(gè)行列,這些行列會(huì)均勻地散布在不同的broker服務(wù)器上。rocketmq行列的概念和kafka的分區(qū)概念是根本共同的,kafka同一個(gè)topic的分區(qū)盡或許地散布在不同的broker上,分區(qū)副本也會(huì)散布在不同的broker上。
rocketmq集群的slave會(huì)從master拉取數(shù)據(jù)備份,master散布在不同的broker上。
activemq:支撐簡(jiǎn)略集群辦法,比方'主-備',對(duì)高檔集群辦法支撐欠好。
八、辦理界面
Kafka:一般 rabbitmq:好 zeromq:無 rocketmq:無 activemq:一般
九、可用性
Kafka:十分高(散布式) rabbitmq:高(主從) zeromq:高。rocketmq:十分高(散布式) activemq:高(主從)
十、音訊重復(fù)
Kafka:支撐at least once、at most once
rabbitmq:支撐at least once、at most once
zeromq:只要重傳機(jī)制,可是沒有耐久化,音訊丟了重傳也沒有用。既不是at least once、也不是at most once、更不是exactly only once
rocketmq:支撐at least once
activemq:支撐at least once
十一、吞吐量TPS
Kafka:極大 Kafka按批次發(fā)送音訊和消費(fèi)音訊。發(fā)送端將多個(gè)小音訊合并,批量發(fā)向Broker,消費(fèi)端每次取出一個(gè)批次的音訊批量處理。rabbitmq:比較大 zeromq:極大 rocketmq:大 rocketMQ接納端能夠批量消費(fèi)音訊,能夠裝備每次消費(fèi)的音訊數(shù),可是發(fā)送端不是批量發(fā)送。activemq:比較大
十二、訂閱辦法和音訊分發(fā)
Kafka:依據(jù)topic以及依照topic進(jìn)行正則匹配的發(fā)布訂閱辦法。
【發(fā)送】
發(fā)送端由topic和key來決議音訊發(fā)往哪個(gè)分區(qū),假如key為null,那么會(huì)運(yùn)用輪詢算法將音訊均衡地發(fā)送到同一個(gè)topic的不同分區(qū)中。假如key不為null,那么會(huì)依據(jù)key的hashcode取模計(jì)算出要發(fā)往的分區(qū)。
【接納】
1>consumer向群組協(xié)調(diào)器broker發(fā)送心跳來維持他們和群組的從屬關(guān)系以及他們對(duì)分區(qū)的一切權(quán)關(guān)系,一切權(quán)關(guān)系一旦被分配就不會(huì)改變除非產(chǎn)生再均衡(比方有一個(gè)consumer參加或許脫離consumer group),consumer只會(huì)從對(duì)應(yīng)的分區(qū)讀取音訊。
2>kafka約束consumer個(gè)數(shù)要少于分區(qū)個(gè)數(shù),每個(gè)音訊只會(huì)被同一個(gè) Consumer Group的一個(gè)consumer消費(fèi)(非播送)。
3>kafka的 Consumer Group訂閱同一個(gè)topic,會(huì)盡或許地使得每一個(gè)consumer分配到相同數(shù)量的分區(qū),不同 Consumer Group訂閱同一個(gè)主題相互獨(dú)立,同一個(gè)音訊會(huì)被不同的 Consumer Group處理。
rabbitmq:供給了4種:direct, topic ,Headers和fanout。
【發(fā)送】
先要聲明一個(gè)行列,這個(gè)行列會(huì)被創(chuàng)立或許現(xiàn)已被創(chuàng)立,行列是根本存儲(chǔ)單元。
由exchange和key決議音訊存儲(chǔ)在哪個(gè)行列。
direct>發(fā)送到和bindingKey徹底匹配的行列。
topic>路由key是含有"."的字符串,會(huì)發(fā)送到含有“*”、“#”進(jìn)行含糊匹配的bingKey對(duì)應(yīng)的行列。
fanout>與key無關(guān),會(huì)發(fā)送到一切和exchange綁定的行列
headers>與key無關(guān),音訊內(nèi)容的headers特點(diǎn)(一個(gè)鍵值對(duì))和綁定鍵值對(duì)徹底匹配時(shí),會(huì)發(fā)送到此行列。此辦法功能低一般不必
【接納】
rabbitmq的行列是根本存儲(chǔ)單元,不再被分區(qū)或許分片,關(guān)于咱們現(xiàn)已創(chuàng)立了的行列,消費(fèi)端要指定從哪一個(gè)行列接納音訊。
當(dāng)rabbitmq行列具有多個(gè)顧客的時(shí)分,行列收到的音訊將以輪詢的分發(fā)辦法發(fā)送給顧客。每條音訊只會(huì)發(fā)送給訂閱列表里的一個(gè)顧客,不會(huì)重復(fù)。
這種辦法十分合適擴(kuò)展,并且是專門為并發(fā)程序設(shè)計(jì)的。
假如某些顧客的使命比較深重,那么能夠設(shè)置basicQos約束信道上顧客能堅(jiān)持的最大未承認(rèn)音訊的數(shù)量,在到達(dá)上限時(shí),rabbitmq不再向這個(gè)顧客發(fā)送任何音訊。
zeromq:點(diǎn)對(duì)點(diǎn)(p2p)
rocketmq:依據(jù)topic/messageTag以及依照音訊類型、特點(diǎn)進(jìn)行正則匹配的發(fā)布訂閱辦法
【發(fā)送】
發(fā)送音訊經(jīng)過輪詢行列的辦法發(fā)送,每個(gè)行列接納均勻的音訊量。發(fā)送音訊指定topic、tags、keys,無法指定投遞到哪個(gè)行列(沒有意義,集群消費(fèi)和播送消費(fèi)跟音訊寄存在哪個(gè)行列沒有關(guān)系)。
tags選填,類似于 Gmail 為每封郵件設(shè)置的標(biāo)簽,方便服務(wù)器過濾運(yùn)用?,F(xiàn)在只支 持每個(gè)音訊設(shè)置一個(gè) tag,所以也能夠類比為 Notify 的 MessageType 概念。
keys選填,代表這條音訊的事務(wù)關(guān)鍵詞,服務(wù)器會(huì)依據(jù) keys 創(chuàng)立哈希索引,設(shè)置后, 能夠在 Console 體系依據(jù) Topic、Keys 來查詢音訊,因?yàn)槭枪K饕?,?qǐng)盡或許 確保 key 僅有,例如訂單號(hào),產(chǎn)品 Id 等。
【接納】
1>播送消費(fèi)。一條音訊被多個(gè)Consumer消費(fèi),即便Consumer屬于同一個(gè)ConsumerGroup,音訊也會(huì)被ConsumerGroup中的每個(gè)Consumer都消費(fèi)一次。
2>集群消費(fèi)。一個(gè) Consumer Group中的Consumer實(shí)例均勻分?jǐn)傁M(fèi)音訊。例如某個(gè)Topic有 9 條音訊,其間一個(gè)Consumer Group有3個(gè)實(shí)例,那么每個(gè)實(shí)例只消費(fèi)其間的 3 條音訊。即每一個(gè)行列都把音訊輪番分發(fā)給每個(gè)consumer。
activemq:點(diǎn)對(duì)點(diǎn)(p2p)、播送(發(fā)布-訂閱)
點(diǎn)對(duì)點(diǎn)辦法,每個(gè)音訊只要1個(gè)顧客;
發(fā)布/訂閱辦法,每個(gè)音訊能夠有多個(gè)顧客。
【發(fā)送】
點(diǎn)對(duì)點(diǎn)辦法:先要指定一個(gè)行列,這個(gè)行列會(huì)被創(chuàng)立或許現(xiàn)已被創(chuàng)立。
發(fā)布/訂閱辦法:先要指定一個(gè)topic,這個(gè)topic會(huì)被創(chuàng)立或許現(xiàn)已被創(chuàng)立。
【接納】
點(diǎn)對(duì)點(diǎn)辦法:關(guān)于現(xiàn)已創(chuàng)立了的行列,消費(fèi)端要指定從哪一個(gè)行列接納音訊。
發(fā)布/訂閱辦法:關(guān)于現(xiàn)已創(chuàng)立了的topic,消費(fèi)端要指定訂閱哪一個(gè)topic的音訊。
十三、次序音訊
Kafka:支撐。
設(shè)置出產(chǎn)者的max.in.flight.requests.per.connection為1,能夠確保音訊是依照發(fā)送次序?qū)懭敕?wù)器的,即便產(chǎn)生了重試。
kafka確保同一個(gè)分區(qū)里的音訊是有序的,可是這種有序分兩種狀況
1>key為null,音訊逐一被寫入不同主機(jī)的分區(qū)中,可是關(guān)于每個(gè)分區(qū)依然是有序的
2>key不為null , 音訊被寫入到同一個(gè)分區(qū),這個(gè)分區(qū)的音訊都是有序。
rabbitmq:不支撐
zeromq:不支撐
rocketmq:支撐
activemq:不支撐
十四、音訊承認(rèn)
Kafka:支撐。
1>發(fā)送方承認(rèn)機(jī)制
ack=0,不管音訊是否成功寫入分區(qū)
ack=1,音訊成功寫入領(lǐng)袖分區(qū)后,回來成功
ack=all,音訊成功寫入一切分區(qū)后,回來成功。
2>接納方承認(rèn)機(jī)制
主動(dòng)或許手動(dòng)提交分區(qū)偏移量,早期版別的kafka偏移量是提交給Zookeeper的,這樣使得zookeeper的壓力比較大,更新版別的kafka的偏移量是提交給kafka服務(wù)器的,不再依賴于zookeeper群組,集群的功能愈加穩(wěn)定。
rabbitmq:支撐。
1>發(fā)送方承認(rèn)機(jī)制,音訊被投遞到一切匹配的行列后,回來成功。假如音訊和行列是可耐久化的,那么在寫入磁盤后,回來成功。支撐批量承認(rèn)和異步承認(rèn)。
2>接納方承認(rèn)機(jī)制,設(shè)置autoAck為false,需求顯式承認(rèn),設(shè)置autoAck為true,主動(dòng)承認(rèn)。
當(dāng)autoAck為false的時(shí)分,rabbitmq行列會(huì)分成兩部分,一部分是等候投遞給consumer的音訊,一部分是現(xiàn)已投遞可是沒收到承認(rèn)的音訊。假如一向沒有收到承認(rèn)信號(hào),并且consumer現(xiàn)已斷開銜接,rabbitmq會(huì)安排這個(gè)音訊重新進(jìn)入行列,投遞給原來的顧客或許下一個(gè)顧客。
未承認(rèn)的音訊不會(huì)有過期時(shí)刻,假如一向沒有承認(rèn),并且沒有斷開銜接,rabbitmq會(huì)一向等候,rabbitmq允許一條音訊處理的時(shí)刻能夠很久很久。
zeromq:支撐。
rocketmq:支撐。
activemq:支撐。
十五、音訊回溯
Kafka:支撐指定分區(qū)offset方位的回溯。rabbitmq:不支撐 zeromq:不支撐 rocketmq:支撐指守時(shí)刻點(diǎn)的回溯。activemq:不支撐
十六、音訊重試
Kafka:不支撐,可是能夠完成。
kafka支撐指定分區(qū)offset方位的回溯,能夠完成音訊重試。
rabbitmq:不支撐,可是能夠利用音訊承認(rèn)機(jī)制完成。
rabbitmq接納方承認(rèn)機(jī)制,設(shè)置autoAck為false。
當(dāng)autoAck為false的時(shí)分,rabbitmq行列會(huì)分成兩部分,一部分是等候投遞給consumer的音訊,一部分是現(xiàn)已投遞可是沒收到承認(rèn)的音訊。假如一向沒有收到承認(rèn)信號(hào),并且consumer現(xiàn)已斷開銜接,rabbitmq會(huì)安排這個(gè)音訊重新進(jìn)入行列,投遞給原來的顧客或許下一個(gè)顧客。
zeromq:不支撐,
rocketmq:支撐。
音訊消費(fèi)失利的大部分場(chǎng)景下,立即重試99%都會(huì)失利,所以rocketmq的戰(zhàn)略是在消費(fèi)失利時(shí)守時(shí)重試,每次時(shí)刻距離相同。
1>發(fā)送端的 send 辦法自身支撐內(nèi)部重試,重試邏輯如下:
a)至多重試3次;
b)假如發(fā)送失利,則輪轉(zhuǎn)到下一個(gè)broker;
c)這個(gè)辦法的總耗時(shí)不超越sendMsgTimeout 設(shè)置的值,默認(rèn) 10s,超越時(shí)刻不在重試。
2>接納端。
Consumer 消費(fèi)音訊失利后,要供給一種重試機(jī)制,令音訊再消費(fèi)一次。Consumer 消費(fèi)音訊失利一般能夠分為以下兩種狀況:
- 因?yàn)橐粲嵶陨淼脑颍绶葱蛄谢Ю?,音訊?shù)據(jù)自身無法處理(例如話費(fèi)充值,當(dāng)時(shí)音訊的手機(jī)號(hào)被
注銷,無法充值)等。守時(shí)重試機(jī)制,比方過 10s 秒后再重試。
- 因?yàn)橐蕾嚨南掠螒?yīng)用服務(wù)不可用,例如 db 銜接不可用,外體系網(wǎng)絡(luò)不可達(dá)等。
即便越過當(dāng)時(shí)失利的音訊,消費(fèi)其他音訊相同也會(huì)報(bào)錯(cuò)。這種狀況能夠 sleep 30s,再消費(fèi)下一條音訊,減輕 Broker 重試音訊的壓力。
activemq:不支撐
十七、并發(fā)度
Kafka:高
一個(gè)線程一個(gè)顧客,kafka約束顧客的個(gè)數(shù)要小于等于分區(qū)數(shù),假如要進(jìn)步并行度,能夠在顧客中再敞開多線程,或許添加consumer實(shí)例數(shù)量。
rabbitmq:極高
自身是用Erlang言語寫的,并發(fā)功能高。
可在顧客中敞開多線程,最常用的做法是一個(gè)channel對(duì)應(yīng)一個(gè)顧客,每一個(gè)線程操縱一個(gè)channel,多個(gè)線程復(fù)用connection的tcp銜接,削減功能開銷。
當(dāng)rabbitmq行列具有多個(gè)顧客的時(shí)分,行列收到的音訊將以輪詢的分發(fā)辦法發(fā)送給顧客。每條音訊只會(huì)發(fā)送給訂閱列表里的一個(gè)顧客,不會(huì)重復(fù)。
這種辦法十分合適擴(kuò)展,并且是專門為并發(fā)程序設(shè)計(jì)的。
假如某些顧客的使命比較深重,那么能夠設(shè)置basicQos約束信道上顧客能堅(jiān)持的最大未承認(rèn)音訊的數(shù)量,在到達(dá)上限時(shí),rabbitmq不再向這個(gè)顧客發(fā)送任何音訊。
zeromq:高
rocketmq:高
1>rocketmq約束顧客的個(gè)數(shù)少于等于行列數(shù),可是能夠在顧客中再敞開多線程,這一點(diǎn)和kafka是共同的,進(jìn)步并行度的辦法相同。
修正消費(fèi)并行度辦法
a) 同一個(gè) ConsumerGroup 下,經(jīng)過添加 Consumer 實(shí)例數(shù)量來進(jìn)步并行度,超越訂閱行列數(shù)的 Consumer實(shí)例無效。
b) 進(jìn)步單個(gè) Consumer 的消費(fèi)并行線程,經(jīng)過修正參數(shù)consumeThreadMin、consumeThreadMax
2>同一個(gè)網(wǎng)絡(luò)銜接connection,客戶端多個(gè)線程能夠一起發(fā)送懇求,銜接會(huì)被復(fù)用,削減功能開銷。
activemq:高
單個(gè)ActiveMQ的接納和消費(fèi)音訊的速度在1萬筆/秒(耐久化 一般為1-2萬, 非耐久化 2 萬以上),在出產(chǎn)環(huán)境中布置10個(gè)Activemq就能到達(dá)10萬筆/秒以上的功能,布置越多的activemq broker 在MQ上latency也就越低,體系吞吐量也就越高。