掃描下方海報二維碼,試聽課程:
面試
(課程詳細大綱,請參見文末)redis
限時折扣 99元(原價199元)
數據庫
僅限 7.22 ~ 7.28 預售周服務器
-------------------------------------------------架構
目錄elasticsearch
TB級數據放在一臺機器上:難啊!分佈式
到底啥是分佈式存儲?oop
啥又是分佈式存儲系統?學習
某臺機器宕機了咋辦?大數據
Master節點如何感知到數據副本消失?
如何複製副本保持足夠副本數量?
刪除多餘副本又該怎麼作呢?
全文總結
「 這篇文章,咱們將用很是淺顯易懂的語言,跟你們聊聊大規模分佈式系統的容錯架構設計。
雖然定位是有「分佈式」、「容錯架構」等看起來略顯複雜的字眼,可是我們仍是按照老規矩:大白話 + 手繪數張彩圖,逐步遞進,讓每一個同窗都能看懂這種複雜架構的設計思想。
我們就用分佈式存儲系統舉例,來聊一下容錯架構的設計。
首先,咱們來瞧瞧,到底啥是分佈式存儲系統呢?
其實特別的簡單,我們就用數據庫裏的一張表來舉例。
好比你手頭有個數據庫,數據庫裏有一張特別大的表,裏面有幾十億,甚至上百億的數據。
更進一步說,假設這一張表的數據量多達幾十個TB,甚至上百個TB,這時你以爲咋樣?
固然是心裏感到恐慌和無助了,由於若是你用MySQL之類的數據庫,單臺數據庫服務器上的磁盤可能都不夠放這一張表的數據!
我們就來看看下面的這張圖,來感覺一下。
因此,假如你手頭有一個超大的數據集,幾百TB!那你仍是別考慮傳統的數據庫技術來存放了。
由於用一臺數據庫服務器可能根本都放不下,因此咱們考慮一下分佈式存儲技術?對了!這纔是解決這個問題的辦法。
我們徹底能夠搞多臺機器嘛!好比搞20臺機器,每臺機器上就放1/20的數據。
舉個例子,好比總共20TB的數據,在每臺機器上只要把1TB就能夠了,1TB應該還好吧?每臺機器均可以輕鬆加愉快的放下這麼多數據了
因此說,把一個超大的數據集拆分紅多片,給放到多臺機器上去,這就是所謂的分佈式存儲。
我們再看看下面的圖。
分佈式存儲系統,固然就是負責把一個超大數據集拆分紅多塊,而後放到多臺機器上來存儲,接着統一管理這些分散在多臺機器上存儲的數據的一套系統。
好比說經典的hadoop就是這類系統,而後fastdfs也是相似的。
若是能夠腦洞打開,從思想本質共通的層面出發,那你會發現,其實相似elasticsearch、redis cluster等等系統,他本質都是如此。
這些都是基於分佈式的系統架構,把超大數據拆分紅多片給你存放在多臺機器上。
我們這篇文章是從分佈式系統架構層面出發,不拘泥於任何一種技術,因此姑且能夠設定:這套分佈式存儲系統,有兩種進程。
一個進程是Master節點,就在一臺機器上,負責統一管控分散在多臺機器上的數據。
另一批進程叫作Slave節點,每臺機器上都有一個Slave節點,負責管理那臺機器上的數據,跟Master節點進行通訊。
我們看看下面的圖,經過圖再來直觀的看看上面的描述。
這個時候又有一個問題了,那麼萬一上面那20臺機器上,其中1臺機器宕機了咋整呢?
這就尷尬了,兄弟,這會致使原本完整的一份20TB的數據,最後有19TB還在了,有1TB的數據就搞丟了,由於那臺機器宕機了啊。
因此說你固然不能容許這種狀況的發生,這個時候就必須作一個數據副本的策略。
好比說,咱們徹底能夠給每一臺機器上的那1TB的數據作2個副本的冗餘,放在別的機器上,而後呢,萬一說某一臺機器宕機,沒事啊,由於其餘機器上還有他的副本。
咱們來看看這種多副本冗餘的架構設計圖。
上面那個圖裏的淺藍色的「1TB數據01」,表明的是20TB數據集中的第一個1TB數據分片。
圖中能夠看到,他就有3個副本,分別在三臺機器中都有淺藍色的方塊,表明了他的三個副本。
這樣的話,一份數據就有了3個副本了。其餘的數據也是相似。
這個時候咱們假設有一臺機器宕機了,好比下面這臺機器宕機,必然會致使「1TB數據01」這個數據分片的其中一個數據副本丟失。以下圖所示:
那這個時候要緊嗎?沒關係,由於「1TB數據01」這個數據分片,他還有另外2個副本在存活的兩臺機器上呢!
因此若是有人要讀取數據,徹底能夠從另外兩臺機器上隨便挑一個副原本讀取就能夠了,數據不會丟的,沒關係張,大兄弟。
如今有一個問題,好比說有個兄弟要讀取「1TB數據01」這個數據分片,那麼他就會找Master節點,說:
「你能不能告訴我「1TB數據01」這個數據分片人在哪裏啊?在哪臺機器上啊?我須要讀他啊!」
咱們來看看下面的圖。
那麼這個時候,Master節點就須要從「1TB數據01」的3個副本里選擇一個出來,告訴人家說:
「兄弟,在哪臺哪臺機器上,有1個副本,你能夠去那臺機器上讀「1TB數據01」的一個副本就ok了。」
可是如今的問題是,Master節點此時還不知道「1TB數據01」的副本3已經丟失了,那萬一Master節點仍是通知人家去讀取一個已經丟失的副本3,確定是不能夠的。
咱們怎麼才能讓Master節點知道副本3已經丟失了呢?
其實也很簡單,每臺機器上負責管理數據的Slave節點,都每隔幾秒(好比說1秒)給Master節點發送一個心跳。
那麼,一旦Master節點發現一段時間(好比說30秒內)沒收到某個Slave節點發送過來的心跳,此時就會認爲這個Slave節點所在機器宕機了,那臺機器上的數據副本都丟失了,而後Master節點就不會告訴別人去讀那個丟失的數據副本。
你們看看下面的圖,一旦Slave節點宕機,Master節點收不到心跳,就會認爲那臺機器上的副本3就已經丟失了,此時絕對不會讓別人去讀那臺宕機機器上的副本3。
那麼此時,Master節點就能夠通知人家去讀「1TB數據01」的副本1或者副本2,哪一個都行,由於那兩個副本其實仍是在的。
舉個例子,好比能夠通知客戶端去讀副本1,此時客戶端就能夠找那臺機器上的Slave節點說要讀取那個副本1。
整個過程以下圖所示。
這個時候又有另一個問題,那就是「1TB數據01」這個數據分片此時只有副本1和副本2這兩個副本了,這就不足夠3個副本啊。
由於咱們預設的是每一個數據分片都得有3個副本的。你們想一想,此時如何給這個數據分片增長1個副本呢?
很簡單,Master節點一旦感知到某臺機器宕機,就能感知到某個數據分片的副本數量不足了。
此時,就會生成一個副本複製的任務,挑選另一臺機器來從有副本的機器去複製一個副本。
好比看下面的圖,能夠挑選第四臺機器從第二臺機器去複製一個副本。
可是,如今這個複製任務是有了,咱們怎麼讓機器4知道呢?
其實也很簡單,機器4不是每秒都會發送一次心跳麼?當機器4發送心跳過去的時候,Master節點就經過心跳響應把這個複製任務下發給機器4,讓機器4從機器2複製一個副本好了。
一樣,咱們來一張圖,看看這個過程:
看上圖,如今機器4上是否是又多了一個「1TB數據01」的副本3 ?那麼「1TB數據01」這個數據分片是否是又變成3個副本了?
那反過來,若是說此時機器3忽然恢復了,他上面也有一個「1TB數據01」的副本3,至關於此時「1TB數據01」就有4個副本了,副本不就多餘了嗎?
不要緊,一旦Master節點感知到機器3復活,會發現副本數量過多,此時會生成一個刪除副本任務。
他會在機器3發送心跳的時候,下發一個刪除副本的指令,讓機器3刪除本身本地多餘的副本就能夠了。這樣,就能夠保持副本數量只有3個。
同樣的,你們來看看下面的圖。
好了,到這裏,經過超級大白話的講解,還有十多張圖的漸進式演進說明,相信你們之前即便不瞭解分佈式系統,都絕對能理解一個分佈式系統的完整的數據容錯架構是如何設計的了。
實際上,這種數據分片存儲 、多副本冗餘、宕機感知、自動副本遷移、多餘副本刪除,這套機制,對於hadoop、elasticsearch等不少系統來講,都是相似的。
因此筆者在這裏強烈建議你們,必定好好吸取一下這種分佈式系統、中間件系統底層數據容錯架構的思想。
這樣,之後學習相似的一些技術的時候,對他們的原理、思想都會感到一種似曾相識的感受。
END
《21天互聯網Java進階面試訓練營(分佈式篇)》詳細目錄,掃描圖片末尾的二維碼,試聽課程