25 落地第一步:設(shè)計(jì)一套高可用的消息中間件生產(chǎn)部署架構(gòu)

落地第一步:設(shè)計(jì)一套高可用的消息中間件生產(chǎn)部署架構(gòu)
1、MQ生產(chǎn)部署架構(gòu)的設(shè)計(jì)任務(wù)
經(jīng)過上一次的技術(shù)分享,小猛基本上把RocketMQ的核心工作原理都搞明白了,接著下一步明哥給他的任務(wù)就是基于RocketMQ的核心原理,去設(shè)計(jì)一套R(shí)ocketMQ的生產(chǎn)部署架構(gòu)出來。
在這套生產(chǎn)部署架構(gòu)中,需要著重考慮到高可用的問題,要保證整個(gè)系統(tǒng)運(yùn)行過程中任何一個(gè)環(huán)節(jié)宕機(jī)都不能影響系統(tǒng)的整體運(yùn)行。
小猛在接受了這個(gè)任務(wù)之后,就開始埋頭設(shè)計(jì)起了MQ的生產(chǎn)部署架構(gòu),幾天之后就搞定了這套架構(gòu)設(shè)計(jì),然后他找明哥單獨(dú)到一個(gè)小會(huì)議室里,開始給明哥講他構(gòu)思的這套MQ的生產(chǎn)部署架構(gòu)。
2、NameServer集群化部署,保證高可用性
首先第一步,我們要讓NameServer集群化部署,我建議可以部署在三臺(tái)機(jī)器上,這樣可以充分保證NameServer作為路由中心的可用性,哪怕是掛掉兩臺(tái)機(jī)器,只要有一個(gè)NameServer還在運(yùn)行,就能保證MQ系統(tǒng)的穩(wěn)定性。
小猛說著,打開了架構(gòu)方案里的第一張圖。
? ? ? ? ? ?

?? ? ? ? ? ?
因?yàn)槲疑洗畏窒淼臅r(shí)候也說了,NameServer的設(shè)計(jì)是采用的Peer-to-Peer的模式來做的,也就是可以集群化部署,但是里面任何一臺(tái)機(jī)器都是獨(dú)立運(yùn)行的,跟其他的機(jī)器沒有任何通信。
每臺(tái)NameServer實(shí)際上都會(huì)有完整的集群路由信息,包括所有的Broker節(jié)點(diǎn)信息,我們的數(shù)據(jù)信息,等等。所以只要任何一臺(tái)NameServer存活下來,就可以保證MQ系統(tǒng)正常運(yùn)行,不會(huì)出現(xiàn)故障。
因此NameServer的集群化部署是必須的第一步。
3、基于Dledger的Broker主從架構(gòu)部署
其次,就是要考慮我們的Broker集群應(yīng)該如何部署,采用什么方式來部署。
經(jīng)過上次的分享我們已經(jīng)知道,如果采用RocketMQ 4.5以前的那種普通的Master-Slave架構(gòu)來部署,能在一定程度上保證數(shù)據(jù)不丟失,也能保證一定的可用性。
但是那種方式的缺陷是很明顯的,最大的問題就是當(dāng)Master Broker掛了之后,沒辦法讓Slave Broker自動(dòng)切換為新的Master Broker,需要手工做一些運(yùn)維操作,修改配置以及重啟機(jī)器才行,這個(gè)非常麻煩。
在手工運(yùn)維的期間,可能就會(huì)導(dǎo)致系統(tǒng)的不可用。
所以既然現(xiàn)在RocketMQ 4.5之后已經(jīng)基于Dledger技術(shù)實(shí)現(xiàn)了可以自動(dòng)讓Slave切換為Master的功能,那么我們肯定是選擇基于Dledger的主備自動(dòng)切換的功能來進(jìn)行生產(chǎn)架構(gòu)的部署。
而且Dledger技術(shù)是要求至少得是一個(gè)Master帶兩個(gè)Slave,這樣有三個(gè)Broke組成一個(gè)Group,也就是作為一個(gè)分組來運(yùn)行。一旦Master宕機(jī),他就可以從剩余的兩個(gè)Slave中選舉出來一個(gè)新的Master對外提供服務(wù)。
此時(shí)小猛又打開了一個(gè)圖。
? ? ? ? ? ?

? ? ? ? ? ? ?
每個(gè)Broker(不論是Master和Slave)都會(huì)把自己注冊到所有的NameServer上去。
注:圖中沒有畫出Slave Broker注冊到NameServer。
然后Master Broker還會(huì)把數(shù)據(jù)同步給兩個(gè)Slave Broker,保證一份數(shù)據(jù)在不同機(jī)器上有多份副本。
4、Broker是如何跟NameServer進(jìn)行通信的?
小猛說到這里停頓了一下,想了想然后繼續(xù)說到,之前我們分享的時(shí)候就說過,這個(gè)Broker會(huì)每隔30秒發(fā)送心跳到所有的NameServer上去,然后每個(gè)NameServer都會(huì)每隔10s檢查一次有沒有哪個(gè)Broker超過120s沒發(fā)送心跳的,如果有,就認(rèn)為那個(gè)Broker已經(jīng)宕機(jī)了,從路由信息里要摘除這個(gè)Broker。
但是當(dāng)時(shí)沒有講Broker和NameServer進(jìn)行通信的細(xì)節(jié),這里在我們的生產(chǎn)架構(gòu)方案里補(bǔ)充進(jìn)去一些細(xì)節(jié)。
首先,Broker跟NameServer之間的通信是基于什么協(xié)議來進(jìn)行的?
HTTP協(xié)議?RPC調(diào)用?還是TCP長連接?首先我們要搞明白這個(gè)。
在RocketMQ的實(shí)現(xiàn)中,采用的是TCP長連接進(jìn)行通信。
也就是說,Broker會(huì)跟每個(gè)NameServer都建立一個(gè)TCP長連接,然后定時(shí)通過TCP長連接發(fā)送心跳請求過去
小猛說著打開下一張圖,在這個(gè)圖里完善了一些Broker跟NameServer通信的細(xì)節(jié)。? ? ? ??

? ? ? ? ? ?
所以各個(gè)NameServer就是通過跟Broker建立好的長連接不斷收到心跳包,然后定時(shí)檢查Broker有沒有120s都沒發(fā)送心跳包,來判定集群里各個(gè)Broker到底掛掉了沒有。
5、使用MQ的系統(tǒng)都要多機(jī)器集群部署
下一步,我們一定會(huì)有很多的系統(tǒng)使用RocketMQ,有些系統(tǒng)是作為生產(chǎn)者往MQ發(fā)送消息,有些系統(tǒng)是作為消費(fèi)者從MQ獲取消息,當(dāng)然還有的系統(tǒng)是既作為生產(chǎn)者,又作為消費(fèi)者,所以我們要考慮這些系統(tǒng)的部署。
對于這些系統(tǒng)的部署本身不應(yīng)該在MQ的考慮范圍內(nèi),但是我們還是應(yīng)該給出一個(gè)建議,就是無論作為生產(chǎn)者還是消費(fèi)者的系統(tǒng),都應(yīng)該多機(jī)器集群化部署,保證他自己本身作為生產(chǎn)者或者消費(fèi)者的高可用性。
因?yàn)橐粋€(gè)系統(tǒng)如果就部署在一臺(tái)機(jī)器上,然后作為生產(chǎn)者向MQ發(fā)送消息,那么一旦哪天機(jī)器上的生產(chǎn)者系統(tǒng)掛了,整個(gè)流程就斷開了,不能保證高可用性。
但是如果在多臺(tái)機(jī)器上部署生產(chǎn)者系統(tǒng),任何一臺(tái)機(jī)器上的生產(chǎn)者掛了,其他機(jī)器上的生產(chǎn)者系統(tǒng)可以繼續(xù)運(yùn)行。
小猛此時(shí)打開了下一張圖,里面有生產(chǎn)者系統(tǒng)和消費(fèi)者系統(tǒng)集群化部署的示意。
? ? ? ? ? ?

? ? ? ? ? ? ?
上述所說在圖里可以清晰看到,同理消費(fèi)者系統(tǒng)也是集群化部署的,如果一臺(tái)機(jī)器上的消費(fèi)者系統(tǒng)掛了,其他機(jī)器上的消費(fèi)者系統(tǒng)應(yīng)該是可以繼續(xù)運(yùn)行的。
6、MQ的核心數(shù)據(jù)模型:Topic到底是什么?
下一步,生產(chǎn)者和消費(fèi)者都會(huì)往MQ里寫入消息和獲取消息了,但是有一個(gè)問題:
MQ中的數(shù)據(jù)模型是什么?你投遞出去的消息在邏輯上到底是放到哪里去的?是隊(duì)列嗎?還是別的什么呢?
小猛在這里補(bǔ)充了一個(gè)很關(guān)鍵的概念,這個(gè)就是MQ中的核心數(shù)據(jù)模型,Topic。
這個(gè)Topic如果直接翻譯為中文,大概就是主題的意思,但是你要是聽到主題兩個(gè)字瞬間會(huì)覺得很蒙圈,因?yàn)楦杏X上主題似乎是手機(jī)上選擇的各種壁紙主題這種概念,比如換一個(gè)壁紙主題,手機(jī)背景就變了。
所以對Topic還是不能直譯,其實(shí)他表達(dá)的意思就是一個(gè)數(shù)據(jù)集合的意思。
舉個(gè)例子,現(xiàn)在你的訂單系統(tǒng)需要往MQ里發(fā)送訂單消息,那么此時(shí)你就應(yīng)該建一個(gè)Topic,他的名字可以叫做:topic_order_info,也就是一個(gè)包含了訂單信息的數(shù)據(jù)集合。
然后你的訂單系統(tǒng)投遞的訂單消息都是進(jìn)入到這個(gè)“topic_order_info”里面去的,如果你的倉儲(chǔ)系統(tǒng)要獲取訂單消息,那么他可以指定從“topic_order_info”這里面去獲取消息,獲取出來的都是他想要的訂單消息了。
一句話:Topic其實(shí)就是一個(gè)數(shù)據(jù)集合的意思,不同類型的數(shù)據(jù)你得放不同的Topic里去。
要是你有一些商品數(shù)據(jù)要發(fā)送消息到MQ里,你就應(yīng)該創(chuàng)建一個(gè)Topic叫做“topic_product_info”,代表里面都是商品數(shù)據(jù),那些想要從MQ里獲取商品數(shù)據(jù)的系統(tǒng)就可以從“topic_product_info”里獲取了。
所以簡單來說,你的系統(tǒng)如果要往MQ里寫入消息或者獲取消息,首先得創(chuàng)建一些Topic,作為數(shù)據(jù)集合存放不同類型的消息,比如說訂單Topic,商品Topic,等等。
7、Topic作為一個(gè)數(shù)據(jù)集合是怎么在Broker集群里存儲(chǔ)的?
下一個(gè)問題:我們創(chuàng)建的那些Topic是怎么存儲(chǔ)在Broker集群里的呢?
這里就體現(xiàn)出來一個(gè)分布式存儲(chǔ)的概念了。
首先我們來想一下,比如我們有一個(gè)訂單Topic,可能訂單系統(tǒng)每天都會(huì)往里面投遞幾百萬條數(shù)據(jù),然后這些數(shù)據(jù)在MQ集群上還得保留好多天,那么最終可能會(huì)有幾千萬的數(shù)據(jù)量,這還只是一個(gè)Topic。
那么如果有很多的Topic,并且里面都有大量的數(shù)據(jù),最終加起來的總和也許是一個(gè)驚人的數(shù)字,此時(shí)這么大量的數(shù)據(jù)本身是不太可能存放在一臺(tái)機(jī)器上的。
如果一臺(tái)機(jī)器沒法放下那么多的數(shù)據(jù),應(yīng)該怎么辦呢?
很簡單,分布式存儲(chǔ)。
我們可以在創(chuàng)建Topic的時(shí)候指定讓他里面的數(shù)據(jù)分散存儲(chǔ)在多臺(tái)Broker機(jī)器上,比如一個(gè)Topic里有1000萬條數(shù)據(jù),此時(shí)有2臺(tái)Broker,那么就可以讓每臺(tái)Broker上都放500萬條數(shù)據(jù)。
這樣就可以把一個(gè)Topic代表的數(shù)據(jù)集合分布式存儲(chǔ)在多臺(tái)機(jī)器上了。
小猛說著,打開了一個(gè)圖,在這個(gè)圖里,新畫出來了一個(gè)Master Broker和兩個(gè)Slave Broker,因?yàn)镈ledger技術(shù)要求每個(gè)Master都得帶兩個(gè)Slave來進(jìn)行選舉。然后示意出來了一個(gè)訂單Topic的數(shù)據(jù)分布式存儲(chǔ)在兩個(gè)Master Broker上了。
? ? ? ? ? ?

?? ? ? ? ? ?
而且另外很重要的一件事是,每個(gè)Broke在進(jìn)行定時(shí)的心跳匯報(bào)給NameServer的時(shí)候,都會(huì)告訴NameServer自己當(dāng)前的數(shù)據(jù)情況,比如有哪些Topic的哪些數(shù)據(jù)在自己這里,這些信息都是屬于路由信息的一部分。
小猛說著在上面的圖里畫了一個(gè)紅圈,示意了Broker心跳的時(shí)候會(huì)匯報(bào)給NameServer自己的數(shù)據(jù)情況,這樣每個(gè)NameServer都知道集群里有哪些Broker,每個(gè)Broker存放了哪些Topic的數(shù)據(jù)。
? ? ? ? ? ?

? ? ? ? ? ? ?
8、生產(chǎn)者系統(tǒng)是如何將消息發(fā)送給Broker的?
接著是下一個(gè)問題:生產(chǎn)者系統(tǒng)是如何將消息發(fā)送到Broker的呢?
首先我們之前說過,在發(fā)送消息之前,得先有一個(gè)Topic,然后在發(fā)送消息的時(shí)候你得指定你要發(fā)送到哪個(gè)Topic里面去。
接著既然你知道你要發(fā)送的Topic,那么就可以跟NameServer建立一個(gè)TCP長連接,然后定時(shí)從他那里拉取到最新的路由信息,包括集群里有哪些Broker,集群里有哪些Topic,每個(gè)Topic都存儲(chǔ)在哪些Broker上。
小猛說著打開了一張示意圖,在里面用紅圈示意了拉取路由信息。
? ? ? ? ? ?

?? ? ? ? ? ?
然后生產(chǎn)者系統(tǒng)自然就可以通過路由信息找到自己要投遞消息的Topic分布在哪幾臺(tái)Broker上,此時(shí)可以根據(jù)負(fù)載均衡算法,從里面選擇一臺(tái)Broke機(jī)器出來,比如round robine輪詢算法,或者是hash算法,都可以。
這個(gè)具體的選擇Broker的算法,后面我們在講RocketMQ技術(shù)落地到項(xiàng)目的時(shí)候再來細(xì)說就可以。
總之,選擇一臺(tái)Broker之后,就可以跟那個(gè)Broker也建立一個(gè)TCP長連接,然后通過長連接向Broker發(fā)送消息即可.
Broker收到消息之后就會(huì)存儲(chǔ)在自己本地磁盤里去。小猛說著又打開了一個(gè)圖,在圖里用紅圈圈出了發(fā)送消息的地方。
? ? ? ? ? ?

?? ? ? ? ? ?
這里唯一要注意的一點(diǎn),就是生產(chǎn)者一定是投遞消息到Master Broker的,然后Master Broker會(huì)同步數(shù)據(jù)給他的Slave Brokers,實(shí)現(xiàn)一份數(shù)據(jù)多份副本,保證Master故障的時(shí)候數(shù)據(jù)不丟失,而且可以自動(dòng)把Slave切換為Master提供服務(wù)。
9、消費(fèi)者是如何從Broker上拉取消息的?
消費(fèi)者系統(tǒng)其實(shí)跟生產(chǎn)者系統(tǒng)原理是類似的,他們也會(huì)跟NameServer建立長連接,然后拉取路由信息,接著找到自己要獲取消息的Topic在哪幾臺(tái)Broker上,就可以跟Broker建立長連接,從里面拉取消息了。
小猛說著打開了最后一張圖,也就是最終的MQ生產(chǎn)部署架構(gòu)圖。
? ? ? ? ? ?

?? ? ? ? ? ?
這里唯一要注意的一點(diǎn)是,消費(fèi)者系統(tǒng)可能會(huì)從Master Broker拉取消息,也可能從Slave Broker拉取消息,都有可能,一切都看具體情況。
10、整體架構(gòu):高可用、高并發(fā)、海量消息、可伸縮
小猛指著最終的架構(gòu)圖說,整個(gè)這套生產(chǎn)架構(gòu)是實(shí)現(xiàn)完全高可用的,因?yàn)镹ameServer隨便一臺(tái)機(jī)器掛了都不怕,他是集群化部署的,每臺(tái)機(jī)器都有完整的路由信息;
Broker隨便掛了一臺(tái)機(jī)器也不怕,掛了Slave對集群沒太大影響,掛了Master也會(huì)基于Dledger技術(shù)實(shí)現(xiàn)自動(dòng)Slave切換為Master;
生產(chǎn)者系統(tǒng)和消費(fèi)者系統(tǒng)隨便掛了一臺(tái)都不怕,因?yàn)樗麄兌际羌夯渴鸬?,其他機(jī)器會(huì)接管工作。
而且這個(gè)架構(gòu)可以抗下高并發(fā),因?yàn)榧僭O(shè)訂單系統(tǒng)對訂單Topic要發(fā)起每秒10萬QPS的寫入,那么只要訂單Topic分散在比如5臺(tái)Broker上,實(shí)際上每個(gè)Broker會(huì)承載2萬QPS寫入,也就是說高并發(fā)場景下的10萬QPS可以分散到多臺(tái)Broker上抗下來。
然后集群足以存儲(chǔ)海量消息,因?yàn)樗袛?shù)據(jù)都是分布式存儲(chǔ)的,每個(gè)Topic的數(shù)據(jù)都是存儲(chǔ)在多臺(tái)Broker機(jī)器上的,用集群里多臺(tái)Master Broker就足以存儲(chǔ)海量的消息。
所以,用多個(gè)Master Broker部署的方式,加上Topic分散在多臺(tái)Broker上的機(jī)制,可以抗下高并發(fā)訪問以及海量消息的分布式存儲(chǔ)。
然后每個(gè)Master Broker有兩個(gè)Slave Broker結(jié)合Dledger技術(shù)可以實(shí)現(xiàn)故障時(shí)的自動(dòng)Slave-Master切換,實(shí)現(xiàn)高可用性。
最后,這套架構(gòu)還具備伸縮性,就是說如果要抗更高的并發(fā),存儲(chǔ)跟多的數(shù)據(jù),完全可以在集群里加入更多的Broker機(jī)器,這樣就可以線性擴(kuò)展集群了。
明哥聽完這套生產(chǎn)部署架構(gòu)的設(shè)計(jì),對小猛真是由衷的贊賞,感覺這個(gè)小伙子雖然才剛畢業(yè),但是考慮問題真的很周全,很多細(xì)節(jié)都考慮到了,而且除了細(xì)節(jié)還能進(jìn)行整體架構(gòu)的考慮,真的很不錯(cuò)。
明哥說:小伙子太棒了,我相信你只要有這個(gè)勁頭,后續(xù)一定可以幫助咱們團(tuán)隊(duì)用MQ技術(shù)改造好系統(tǒng)架構(gòu)的。
End
專欄版權(quán)歸公眾號(hào)儒猿技術(shù)窩所有
未經(jīng)許可不得傳播,如有侵權(quán)將追究法律責(zé)任