11張手繪圖:搞定分布式系統(tǒng)容錯(cuò)架構(gòu)
這篇文章,我們將用非常淺顯易懂的語言,跟大家聊聊大規(guī)模分布式系統(tǒng)的容錯(cuò)架構(gòu)設(shè)計(jì)。雖然定位是有“分布式”、“容錯(cuò)架構(gòu)”等看起來略顯復(fù)雜的字眼,但是咱們還是按照老規(guī)矩:大白話 + 手繪數(shù)張彩圖,逐步遞進(jìn),讓每個(gè)同學(xué)都能看懂這種復(fù)雜架構(gòu)的設(shè)計(jì)思想。
1、TB級(jí)數(shù)據(jù)放在一臺(tái)機(jī)器上:難??!
咱們就用分布式存儲(chǔ)系統(tǒng)舉例,來聊一下容錯(cuò)架構(gòu)的設(shè)計(jì)。
首先,我們來瞧瞧,到底啥是分布式存儲(chǔ)系統(tǒng)呢?
其實(shí)特別的簡單,咱們就用數(shù)據(jù)庫里的一張表來舉例。
比如你手頭有個(gè)數(shù)據(jù)庫,數(shù)據(jù)庫里有一張?zhí)貏e大的表,里面有幾十億,甚至上百億的數(shù)據(jù)。
更進(jìn)一步說,假設(shè)這一張表的數(shù)據(jù)量多達(dá)幾十個(gè)TB,甚至上百個(gè)TB,這時(shí)你覺得咋樣?
當(dāng)然是內(nèi)心感到恐慌和無助了,因?yàn)槿绻阌肕ySQL之類的數(shù)據(jù)庫,單臺(tái)數(shù)據(jù)庫服務(wù)器上的磁盤可能都不夠放這一張表的數(shù)據(jù)!
咱們就來看看下面的這張圖,來感受一下。
2、到底啥是分布式存儲(chǔ)?
所以,假如你手頭有一個(gè)超大的數(shù)據(jù)集,幾百TB!那你還是別考慮傳統(tǒng)的數(shù)據(jù)庫技術(shù)來存放了。
因?yàn)橛靡慌_(tái)數(shù)據(jù)庫服務(wù)器可能根本都放不下,所以我們考慮一下分布式存儲(chǔ)技術(shù)?對(duì)了!這才是解決這個(gè)問題的辦法。
咱們完全可以搞多臺(tái)機(jī)器嘛!比如搞20臺(tái)機(jī)器,每臺(tái)機(jī)器上就放1/20的數(shù)據(jù)。
舉個(gè)例子,比如總共20TB的數(shù)據(jù),在每臺(tái)機(jī)器上只要把1TB就可以了,1TB應(yīng)該還好吧?每臺(tái)機(jī)器都可以輕松加愉快的放下這么多數(shù)據(jù)了。
所以說,把一個(gè)超大的數(shù)據(jù)集拆分成多片,給放到多臺(tái)機(jī)器上去,這就是所謂的分布式存儲(chǔ)。
咱們再看看下面的圖。
3、那么啥又是分布式存儲(chǔ)系統(tǒng)呢?
那分布式存儲(chǔ)系統(tǒng)是啥呢?
分布式存儲(chǔ)系統(tǒng),當(dāng)然就是負(fù)責(zé)把一個(gè)超大數(shù)據(jù)集拆分成多塊,然后放到多臺(tái)機(jī)器上來存儲(chǔ),接著統(tǒng)一管理這些分散在多臺(tái)機(jī)器上存儲(chǔ)的數(shù)據(jù)的一套系統(tǒng)。
比如說經(jīng)典的hadoop就是這類系統(tǒng),然后fastdfs也是類似的。
如果你可以腦洞打開,從思想本質(zhì)共通的層面出發(fā),那你會(huì)發(fā)現(xiàn),其實(shí)類似elasticsearch、redis cluster等等系統(tǒng),他本質(zhì)都是如此。
這些都是基于分布式的系統(tǒng)架構(gòu),把超大數(shù)據(jù)拆分成多片給你存放在多臺(tái)機(jī)器上。
咱們這篇文章是從分布式系統(tǒng)架構(gòu)層面出發(fā),不拘泥于任何一種技術(shù),所以姑且可以設(shè)定:這套分布式存儲(chǔ)系統(tǒng),有兩種進(jìn)程。
一個(gè)進(jìn)程是Master節(jié)點(diǎn),就在一臺(tái)機(jī)器上,負(fù)責(zé)統(tǒng)一管控分散在多臺(tái)機(jī)器上的數(shù)據(jù)。
另外一批進(jìn)程叫做Slave節(jié)點(diǎn),每臺(tái)機(jī)器上都有一個(gè)Slave節(jié)點(diǎn),負(fù)責(zé)管理那臺(tái)機(jī)器上的數(shù)據(jù),跟Master節(jié)點(diǎn)進(jìn)行通信。
咱們看看下面的圖,通過圖再來直觀的看看上面的描述。
4、天哪!某臺(tái)機(jī)器宕機(jī)了咋辦?
這個(gè)時(shí)候又有一個(gè)問題了,那么萬一上面那20臺(tái)機(jī)器上,其中1臺(tái)機(jī)器宕機(jī)了咋整呢?
這就尷尬了,兄弟,這會(huì)導(dǎo)致本來完整的一份20TB的數(shù)據(jù),最后有19TB還在了,有1TB的數(shù)據(jù)就搞丟了,因?yàn)槟桥_(tái)機(jī)器宕機(jī)了啊。
所以說你當(dāng)然不能允許這種情況的發(fā)生,這個(gè)時(shí)候就必須做一個(gè)數(shù)據(jù)副本的策略。
比如說,我們完全可以給每一臺(tái)機(jī)器上的那1TB的數(shù)據(jù)做2個(gè)副本的冗余,放在別的機(jī)器上,然后呢,萬一說某一臺(tái)機(jī)器宕機(jī),沒事啊,因?yàn)槠渌麢C(jī)器上還有他的副本。
我們來看看這種多副本冗余的架構(gòu)設(shè)計(jì)圖。
上面那個(gè)圖里的淺藍(lán)色的“1TB數(shù)據(jù)01”,代表的是20TB數(shù)據(jù)集中的第一個(gè)1TB數(shù)據(jù)分片。
圖中可以看到,他就有3個(gè)副本,分別在三臺(tái)機(jī)器中都有淺藍(lán)色的方塊,代表了他的三個(gè)副本。
這樣的話,一份數(shù)據(jù)就有了3個(gè)副本了。其他的數(shù)據(jù)也是類似。
這個(gè)時(shí)候我們假設(shè)有一臺(tái)機(jī)器宕機(jī)了,比如下面這臺(tái)機(jī)器宕機(jī),必然會(huì)導(dǎo)致“1TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片的其中一個(gè)數(shù)據(jù)副本丟失。如下圖所示:
那這個(gè)時(shí)候要緊嗎?不要緊,因?yàn)椤?TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片,他還有另外2個(gè)副本在存活的兩臺(tái)機(jī)器上呢!
所以如果有人要讀取數(shù)據(jù),完全可以從另外兩臺(tái)機(jī)器上隨便挑一個(gè)副本來讀取就可以了,數(shù)據(jù)不會(huì)丟的,不要緊張,大兄弟。
5、Master節(jié)點(diǎn)如何感知到數(shù)據(jù)副本消失?
現(xiàn)在有一個(gè)問題,比如說有個(gè)兄弟要讀取“1TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片,那么他就會(huì)找Master節(jié)點(diǎn),說:
“你能不能告訴我“1TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片人在哪里?。吭谀呐_(tái)機(jī)器上?。课倚枰x他??!”
我們來看看下面的圖。
那么這個(gè)時(shí)候,Master節(jié)點(diǎn)就需要從“1TB數(shù)據(jù)01”的3個(gè)副本里選擇一個(gè)出來,告訴人家說:
“兄弟,在哪臺(tái)哪臺(tái)機(jī)器上,有1個(gè)副本,你可以去那臺(tái)機(jī)器上讀“1TB數(shù)據(jù)01”的一個(gè)副本就ok了?!?/span>
但是現(xiàn)在的問題是,Master節(jié)點(diǎn)此時(shí)還不知道“1TB數(shù)據(jù)01”的副本3已經(jīng)丟失了,那萬一Master節(jié)點(diǎn)還是通知人家去讀取一個(gè)已經(jīng)丟失的副本3,肯定是不可以的。
所以,我們怎么才能讓Master節(jié)點(diǎn)知道副本3已經(jīng)丟失了呢?
其實(shí)也很簡單,每臺(tái)機(jī)器上負(fù)責(zé)管理數(shù)據(jù)的Slave節(jié)點(diǎn),都每隔幾秒(比如說1秒)給Master節(jié)點(diǎn)發(fā)送一個(gè)心跳。
那么,一旦Master節(jié)點(diǎn)發(fā)現(xiàn)一段時(shí)間(比如說30秒內(nèi))沒收到某個(gè)Slave節(jié)點(diǎn)發(fā)送過來的心跳,此時(shí)就會(huì)認(rèn)為這個(gè)Slave節(jié)點(diǎn)所在機(jī)器宕機(jī)了,那臺(tái)機(jī)器上的數(shù)據(jù)副本都丟失了,然后Master節(jié)點(diǎn)就不會(huì)告訴別人去讀那個(gè)丟失的數(shù)據(jù)副本。
大家看看下面的圖,一旦Slave節(jié)點(diǎn)宕機(jī),Master節(jié)點(diǎn)收不到心跳,就會(huì)認(rèn)為那臺(tái)機(jī)器上的副本3就已經(jīng)丟失了,此時(shí)絕對(duì)不會(huì)讓別人去讀那臺(tái)宕機(jī)機(jī)器上的副本3。
那么此時(shí),Master節(jié)點(diǎn)就可以通知人家去讀“1TB數(shù)據(jù)01”的副本1或者副本2,哪個(gè)都行,因?yàn)槟莾蓚€(gè)副本其實(shí)還是在的。
舉個(gè)例子,比如可以通知客戶端去讀副本1,此時(shí)客戶端就可以找那臺(tái)機(jī)器上的Slave節(jié)點(diǎn)說要讀取那個(gè)副本1。
整個(gè)過程如下圖所示。
6、復(fù)制副本保持足夠副本數(shù)量
這個(gè)時(shí)候又有另外一個(gè)問題,那就是“1TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片此時(shí)只有副本1和副本2這兩個(gè)副本了,這就不足夠3個(gè)副本啊。
因?yàn)槲覀冾A(yù)設(shè)的是每個(gè)數(shù)據(jù)分片都得有3個(gè)副本的。大家想想,此時(shí)如何給這個(gè)數(shù)據(jù)分片增加1個(gè)副本呢?
很簡單,Master節(jié)點(diǎn)一旦感知到某臺(tái)機(jī)器宕機(jī),就能感知到某個(gè)數(shù)據(jù)分片的副本數(shù)量不足了。
此時(shí),就會(huì)生成一個(gè)副本復(fù)制的任務(wù),挑選另外一臺(tái)機(jī)器來從有副本的機(jī)器去復(fù)制一個(gè)副本。
比如看下面的圖,可以挑選第四臺(tái)機(jī)器從第二臺(tái)機(jī)器去復(fù)制一個(gè)副本。
但是,現(xiàn)在這個(gè)復(fù)制任務(wù)是有了,我們怎么讓機(jī)器4知道呢?
其實(shí)也很簡單,機(jī)器4不是每秒都會(huì)發(fā)送一次心跳么?當(dāng)機(jī)器4發(fā)送心跳過去的時(shí)候,Master節(jié)點(diǎn)就通過心跳響應(yīng)把這個(gè)復(fù)制任務(wù)下發(fā)給機(jī)器4,讓機(jī)器4從機(jī)器2復(fù)制一個(gè)副本好了。
同樣,我們來一張圖,看看這個(gè)過程:
看上圖,現(xiàn)在機(jī)器4上是不是又多了一個(gè)“1TB數(shù)據(jù)01”的副本3 ?那么“1TB數(shù)據(jù)01”這個(gè)數(shù)據(jù)分片是不是又變成3個(gè)副本了?
7、刪除多余副本
那反過來,如果說此時(shí)機(jī)器3突然恢復(fù)了,他上面也有一個(gè)“1TB數(shù)據(jù)01”的副本3,相當(dāng)于此時(shí)“1TB數(shù)據(jù)01”就有4個(gè)副本了,副本不就多余了嗎?
沒關(guān)系,一旦Master節(jié)點(diǎn)感知到機(jī)器3復(fù)活,會(huì)發(fā)現(xiàn)副本數(shù)量過多,此時(shí)會(huì)生成一個(gè)刪除副本任務(wù)。
他會(huì)在機(jī)器3發(fā)送心跳的時(shí)候,下發(fā)一個(gè)刪除副本的指令,讓機(jī)器3刪除自己本地多余的副本就可以了。這樣,就可以保持副本數(shù)量只有3個(gè)。
一樣的,大家來看看下面的圖。
8、全文總結(jié)
好了,到這里,通過超級(jí)大白話的講解,還有十多張圖的漸進(jìn)式演進(jìn)說明,相信大家以前即使不了解分布式系統(tǒng),都絕對(duì)能理解一個(gè)分布式系統(tǒng)的完整的數(shù)據(jù)容錯(cuò)架構(gòu)是如何設(shè)計(jì)的了。
實(shí)際上,這種數(shù)據(jù)分片存儲(chǔ) 、多副本冗余、宕機(jī)感知、自動(dòng)副本遷移、多余副本刪除,這套機(jī)制,對(duì)于hadoop、elasticsearch等很多系統(tǒng)來說,都是類似的。
所以筆者在這里強(qiáng)烈建議大家,一定好好吸收一下這種分布式系統(tǒng)、中間件系統(tǒng)底層數(shù)據(jù)容錯(cuò)架構(gòu)的思想。
這樣,以后學(xué)習(xí)類似的一些技術(shù)的時(shí)候,對(duì)他們的原理、思想都會(huì)感到一種似曾相識(shí)的感覺。