從生日請客到HDFS工作原理解析

來自:互聯網偵察

 

小史是一個非科班的程序員,雖然學的是電子專業,但是通過自己的努力成功通過了面試,現在要開始迎接新生活了。

對小史面試情況感興趣的同學可以觀看面試現場系列

 

 

今天是小史生日,爲了慶祝自己今年喜提A廠offer,小史叫了二十多個人一起慶生,呂老師、小史姐姐、小林都去啦。

 

到了吃午飯的時間,他們一起去了一家精緻的茶餐廳,四人一桌,坐了六桌。

 

所謂衆口難調,爲了照顧大家,每桌都是自己點菜,小史也是忙前忙後,忙着瞭解大家都點了些啥,畢竟他要付款。

 

服務員一下子面對六桌,菜有點多,有些菜忘了上哪桌,小史也會告訴他們。

 

 

吃着吃着,突然自己桌點的一道芋頭排骨湯進了一個蒼蠅。

 

吃完飯,大家都很開心,回家的路上,小史又拉着呂老師問。

 

【飯後】

 

【分佈式文件系統】

 

小史:這個我當然知道,文件系統就是用來管理文件的一個系統,比如你今天送我的mac pro,我在命令行敲一個ls,就能看到當前目錄的文件。

 

【文件切塊】

 

小史:我明白了,原來是這麼玩的。大文件切塊後分別存儲在多臺機器,然後提供統一的操作接口,看來分佈式文件系統hdfs也是挺簡單的。

 

【潛在問題】

 

呂老師:哈哈,這樣就太慢了,而且效率很低,是一個o(n)的算法。還有啊,我們剛剛說一個文件分別存在幾臺機器上,假如其中一臺機器壞了,那麼這個文件就不能訪問了?

呂老師:那可不對,你可以算一下,假如我有一個1000臺機器組成的分佈式系統,一臺機器每天出現故障的概率是0.1%,那麼整個系統每天出現故障的概率是多大呢?

呂老師:當然有,如果要存儲PB級或者EB級的數據,成千上萬臺機器組成的集羣是很常見的,所以說分佈式系統比單機系統要複雜得多呀。

 

【hdfs架構】

 

呂老師:小史,你可以把每一桌看作是一個DataNode,每道菜看作是一個文件切塊,服務員看作client,你就是NameNode。

呂老師:DataNode是真正存儲數據的地方,NameNode相當於一個管理者master,它知道每一個DataNode的存儲情況,client其實就是那個對外操作的統一接口。

小史:嗯,不需要,他問我就行,我會告訴他。哦,我明白了,client要查詢文件的時候,也是先去NameNode裏面詢問需要找的文件在哪個DataNode上是麼?

小史:因爲其他桌也點了相同的菜,所以我們可以去其他桌吃這個菜啊。等等,我好像知道了,你的意思是hdfs會將數據保存多份是麼?

呂老師:沒錯,hdfs在寫入一個數據塊的時候,不會僅僅寫入一個DataNode,而是會寫入到多個DataNode中,這樣,如果其中一個DataNode壞了,還可以從其餘的DataNode中拿到數據,保證了數據不丟失。

 

【hdfs讀寫流程】

 

小史:沒問題啊,讀取文件大概分爲這幾個步驟:

1、client詢問NameNode,我要讀取某個路徑下的文件,麻煩告訴我這個文件都在哪些DataNode上?

2、NameNode回覆client,這個路徑下的文件被切成了3塊,分別在DataNode1、DataNode3和DataNode4上

3、client去找DataNode1、DataNode3和DataNode4,拿到3個文件塊,通過stream讀取進來

小史:文件寫入也是類似的吧?分爲這幾個步驟:

1、client先將文件分塊,然後詢問NameNode,我要寫入一個文件到某個路徑下,文件有3塊,應該怎麼寫?

2、NameNode回覆client,可以分別寫到

DataNode1、DataNode2、DataNode3、DataNode4上,記住,每個塊重複寫3份,總共是9份

3、client找到

DataNode1、DataNode2、DataNode3、DataNode4,把數據寫到他們上面

由於之前呂老師專門給小史講過mysql的專題,所以小史對mysql的理解還是比較深的。

 

【SecondNameNode】

 

(注:元數據metadata是指描述數據的數據,這裏指描述文件的數據,比如文件路徑,文件被分爲幾塊?每個塊在哪些DataNode上等)

小史:哦,原來是這個問題啊,簡單啊,既然文件的元數據這麼重要,那可以持久化到硬盤上啊,重啓之後再從硬盤把數據恢復到內存不就行了。

小史:對哦,這麼說是要寫,這塊我確實欠考慮,寫入流程應該還要考慮這個,但是如果寫硬盤,還得找到那個文件的元信息的位置,再進行插入或修改,這樣會不會很慢啊?或者我直接把整個文件系統的元數據寫到硬盤,省去查找時間,會不會好點?

呂老師:小史,這次你考慮得很全面,如果每次寫文件都要再去尋找元數據位置,或者把所有元數據在硬盤中同步一份,寫入的效率將大大受到影響,所以hdfs並不是這樣做的。

呂老師:hdfs會把操作日誌記錄下來,存在editlog中,下次重啓的時候,先加載editlog,把所有的日誌都回放一遍,達到重啓前的狀態。

小史:如果NameNode運行了很久,文件操作很多的話,editlog就會很大吧?那麼下次NameNode重啓的時候,需要進行大量操作的恢復,啓動時間就會非常長。

呂老師:哈,小史,你的思維越來越活躍了,沒錯,這確實是一個大問題,不過hdfs的設計者也想到了這個問題。你看看之前hdfs的架構圖,裏面有一個SecondNameNode,就是用來解決這個問題。

呂老師:剛剛其實只說了一半,NameNode確實會回放editlog,但是不是每次都從頭回放,它會先加載一個fsimage,這個文件是之前某一個時刻整個NameNode的文件元數據的內存快照,然後再在這個基礎上回放editlog,完成後,會清空editlog,再把當前文件元數據的內存狀態寫入fsimage,方便下一次加載。

 

【hdfs的HA】

 

小史:我也想到一個問題,NameNode對於hdfs來說是非常重要的,假如NameNode掛了,誰來接替它的工作呢?是SecondNameNode嗎?

呂老師:哈,你這樣想可就大錯特錯啦,這是初學hdfs很容易被誤導的一個地方,NameNode掛了, SecondNameNode並不能替代NameNode,所以如果集羣中只有一個NameNode,它掛了,整個系統就掛了。

呂老師:沒錯,hadoop2.x之前,整個集羣只能有一個NameNode,是有可能發生單點故障的,所以hadoop1.x有本身的不穩定性。但是hadoop2.x之後,我們可以在集羣中配置多個NameNode,就不會有這個問題了,但是配置多個NameNode,需要注意的地方就更多了,系統就更加複雜了。

呂老師:這和系統的設計理念是有關係的,雖然hadoop1.x存在一個NameNode單點,但是它大大簡化了系統的複雜度,並且數據量在一定範圍內時,NameNode並沒有這麼容易掛,所以那個時代是被接受的。但是隨着數據量越來越大,這個單點始終是個隱患,所以設計者不得不升級爲更加複雜的hadoop2.x,來保證NameNode的高可靠。

呂老師:俗話說一山不容二虎,兩個NameNode只能有一個是活躍狀態active,另一個是備份狀態standby,我們看一下兩個NameNode的架構圖。

呂老師:因爲active的NameNode掛了之後,standby的NameNode要馬上接替它,所以它們的數據要時刻保持一致,在寫入數據的時候,兩個NameNode內存中都要記錄數據的元信息,並保持一致。這個JournalNode就是用來在兩個NameNode中同步數據的,並且standby NameNode實現了SecondNameNode的功能。

呂老師:active NameNode有操作之後,它的editlog會被記錄到JournalNode中,standby NameNode會從JournalNode中讀取到變化並進行同步,同時standby NameNode會監聽記錄的變化。

(注意,hadoop2.x如果只部署一個NameNode,還是會用SecondNameNode)

 

【hdfs優缺點

 

小史:可以,hdfs可以存儲海量數據,並且是高可用的,任何一臺機器掛了都有備份,不會影響整個系統的使用,也不會造成數據丟失。

呂老師:哈哈,這到不是主要的。小史,你想想吃飯場景,如果每一桌都點份量小的菜,但是點很多份,那你還能清楚記住哪桌點哪些嗎?

小史:我想我可能記不住了,你的意思是每一個小文件都有元信息,它們都存在NameNode裏面,可能造成NameNode的內存不足?

小史:如果要隨機寫,由於文件被切塊,需要先找到內容在哪個塊,然後讀入內存,修改完成之後再更新所有備份,由於一個塊並不小,這個效率會很低吧?

 

【筆記

 

小史在呂老師的課堂上,趕緊把這次的筆記記錄下來。

 

1、hdfs是一個分佈式文件系統,簡單理解就是多臺機器組成的一個文件系統。

 

2、hdfs中有3個重要的模塊,client對外提供統一操作接口,DataNode真正存儲數據,NameNode協調和管理數據,是一個典型的master-slave架構。

 

3、hdfs會對大文件進行切塊,並且每個切塊會存儲備份,保證數據的高可用,適合存儲大數據。

 

4、NameNode通過fsimage和editlog來實現數據恢復和高可用。

 

5、hdfs不適用於大量小文件存儲,不支持併發寫入,不支持文件隨機修改,查詢效率大概在秒級。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章