HDFS你一定要知道,要考的
你肯定聽過Hadoop,對就是那頭奔跑的小象。

Hadoop作為大數(shù)據(jù)時代代表性的解決方案被大家所熟知,它主要包含兩部分內(nèi)容:
- HDFS分布式文件存儲
- MapReduce分a布式計算框架
前面我們分析存儲方案的發(fā)展的時候有提到分布式文件存儲的出現(xiàn)是為了解決存儲的三大問題:可擴展性,高吞吐量,高可靠性
那么Hadoop的核心HDFS是如何解決上面三個問題的呢?
其實設(shè)計一個系統(tǒng)我們要考慮到它的應(yīng)用場景,然后對它的功能和特性進行設(shè)計,做出取舍。我們可能會關(guān)注這幾個問題:
- 原始存儲格式 or 特殊存儲格式,通過什么格式存儲才能方便的管理數(shù)據(jù),保證數(shù)據(jù)的遷移和安全。
- 大文件 or 小文件,文件系統(tǒng)適合大文件還是小文件存儲,如何提供I/O效率。
- 數(shù)據(jù)高可用 or 空間利用率,通過復(fù)制副本技術(shù)提高數(shù)據(jù)可用性必然會降低空間利用率,應(yīng)該如何取舍。
- 是否有元數(shù)據(jù)服務(wù),元數(shù)據(jù)服務(wù)是保存存儲數(shù)據(jù)元數(shù)據(jù)信息的服務(wù),讀寫數(shù)據(jù)都需要連接元數(shù)據(jù)服務(wù)器保證一致性。存在元數(shù)據(jù)服務(wù)勢必會存在單點問題和性能瓶頸問題。
上面這個4個問題劃重點,要考的!!!
HDFS它的設(shè)計目標就是把超大的數(shù)據(jù)集存儲到多臺普通計算機上,并且可以提供高可靠性和高吞吐量的服務(wù),支持通過添加節(jié)點的方式對集群進行擴容。所以HDFS有著它自己的設(shè)計前提:
- 對存儲大文件支持很好,不適用于存儲大量小文件
- 通過流式訪問數(shù)據(jù),保證高吞吐量而不是低延時的用戶響應(yīng)
- 簡單一致性,使用場景應(yīng)為一次寫入多次讀取,不支持多用戶寫入,不支持任意修改文件。
- 冗余備份機制,空間換可靠性(Hadoop3中引入糾刪碼機制,糾刪碼需通過計算恢復(fù)數(shù)據(jù),實為通過時間換空間,有興趣的可以查看RAID的實現(xiàn))
- 移動計算優(yōu)于移動數(shù)據(jù),為支持大數(shù)據(jù)處理主張移動計算優(yōu)于移動數(shù)據(jù),提供相關(guān)接口。
遵循以上的設(shè)計前提和目標最終的成品就是我們?nèi)粘?yīng)用中的HDFS了。HDFS主要由NameNode和DataNode構(gòu)成,以Master/Slave模式運行。我們來詳細了解一下。

數(shù)據(jù)塊

這個就對應(yīng)前面我們提出的疑問“原始存儲格式 or 特殊存儲格式”,在HDFS上抽象出了一個數(shù)據(jù)塊的概念??梢哉J為是HDFS的特殊存儲格式,當你存儲文件的時候不是以文件為單位進行數(shù)據(jù)存儲的,而是以數(shù)據(jù)塊為單位進行存儲。這樣有什么好處呢?首先,它屏蔽了文件的概念,如果你存一個超大的文件,文件的大小大于你任何一個單個磁盤的大小,在HDFS中會把你的文件切割成多個數(shù)據(jù)塊,存儲到不同機器的不同磁盤中。這樣就簡化了存儲系統(tǒng)的設(shè)計,而且也適用于數(shù)據(jù)的備份、遷移功能,提高了數(shù)據(jù)的容錯性和可用性。
NameNode
這個對應(yīng)前面的疑問“是否有元數(shù)據(jù)服務(wù)”,在HDFS中NameNode就起著元數(shù)據(jù)管理服務(wù)的作用,它管理著整個文件系統(tǒng)的命名空間,維護著文件系統(tǒng)樹詳情并對其持久化。
當我們寫入或者讀取數(shù)據(jù)時都需要先連接NameNode,獲取可操作的DataNode節(jié)點才能繼續(xù)操作。所以NameNode是存在單點問題和性能問題的。Hadoop2中可以配置HA的模式,一個集群擁有兩個NameNode一個處于Active狀態(tài)一個處于Standby狀態(tài),其中一個失效后另一個可以自動切換成Active,進而解決了一部分單點問題。(在Hadoop3中支持配置多個NameNode,進一步解決NameNode的單點問題)。NameNode將元數(shù)據(jù)信息保存在內(nèi)存中,內(nèi)存就是NameNode的性能瓶頸,如果集群中小文件過多會產(chǎn)生大量元數(shù)據(jù)信息占用NameNode的內(nèi)存。所以HDFS對大文件的支持更好。NameNode會占用較多的內(nèi)存和I/O資源,所以運行NameNode的節(jié)點不會啟動DataNode或者執(zhí)行MapReduce任務(wù)。
DataNode
DataNode就是HDFS的工作節(jié)點了,它負責存儲數(shù)據(jù),為客戶端提供數(shù)據(jù)塊的讀寫服務(wù)。在啟動時會將它存儲的數(shù)據(jù)塊的列表發(fā)送給NameNode,根據(jù)NameNode的要求對數(shù)據(jù)塊進行創(chuàng)建、刪除和備份,還會通過心跳定期向NameNode更新存儲數(shù)據(jù)塊信息。
HDFS通過備份副本的方式實現(xiàn)可靠性,Hadoop2缺省的數(shù)據(jù)塊大小為128M,復(fù)制因子為,默認的備份副本的分布位置與機架和節(jié)點有關(guān)。當DataNode丟失連接后,NameNode會把失敗節(jié)點的數(shù)據(jù)(從其他備份副本節(jié)點)復(fù)制到另外一個健康的DataNode節(jié)點,保證集群里面的數(shù)據(jù)庫始終維持指定的副本數(shù)量。
寫流程

- 首先,HDFS Client和NameNode建立連接,告訴NameNode要存儲一個文件。NameNode維護著DataNode的列表,知道哪些DataNode上面還有空間可以進行存儲。
- NameNode通過查看存儲的元數(shù)據(jù)信息,發(fā)現(xiàn)DataNode1,2,3上可以進行存儲。于是他將此信息返回給HDFS Client。
- HDFS Client接受到NameNode的返回的DataNode列表后,Client會與距離最近DataNode1建立連接,讓其準備好接收數(shù)據(jù)。然后將文件進行分塊,將數(shù)據(jù)塊1和NameNode返回的DataNode列表信息一起發(fā)送給DataNode1.
- DataNode1通過列表信息得知要發(fā)送給DataNode2.所以DataNode1將數(shù)據(jù)與列表信息發(fā)送給DataNode2.DataNode2又發(fā)送給DataNode3,此時數(shù)據(jù)塊1已經(jīng)存儲完成并備份了三份。
- 當DataNode1,2,3都接收并存儲數(shù)據(jù)塊1后,會向NameNode發(fā)送信息,告知已經(jīng)接收到了數(shù)據(jù)塊1.并把數(shù)據(jù)塊1相關(guān)信息發(fā)送給NameNode,NameNode更新元數(shù)據(jù)信息并 與Client通信告知數(shù)據(jù)塊1已經(jīng)存儲完畢。然后Client開始進行數(shù)據(jù)塊2的存儲。
這里需要注意的是一個大型的HDFS文件系統(tǒng)一般都是需要跨很多機架的,不同機架之間的數(shù)據(jù)傳輸需要經(jīng)過網(wǎng)關(guān),并且,同一個機架中機器之間的帶寬要大于不同機架機器之間的帶寬。如果把所有的副本都放在不同的機架中,這樣既可以防止機架失敗導(dǎo)致數(shù)據(jù)塊不可用,又可以在讀數(shù)據(jù)時利用到多個機架的帶寬,并且也可以很容易的實現(xiàn)負載均衡。如果副本數(shù)量是3的情況下,HDFS默認把***個副本放到機架的一個節(jié)點上,另一個副本放到同一個機架的另一個節(jié)點上,把***一個節(jié)點放到不同的機架上。這種策略減少了跨機架副本的個數(shù)提高了寫的性能,也能夠允許一個機架失敗的情況,算是一個很好的權(quán)衡。
讀流程

- HDFS Client與NameNode建立鏈接,告訴NameNode要讀取文件xxx。
- NameNode通過查詢自己的元數(shù)據(jù)信息,得到文件xxx的數(shù)據(jù)塊映射信息及存儲數(shù)據(jù)塊的DataNode列表。然后將這些信息發(fā)送給Client。
- Client得到這些信息之后,尋找最近可用的DataNode1.取回數(shù)據(jù)塊1.從DataNode2取回數(shù)據(jù)塊2. 自此成功讀取文件xxx
- 如果DataNode2出現(xiàn)問題掛掉了,則從DataNode3進行數(shù)據(jù)塊讀取。
文件讀取時,NameNode會選擇最近的DataNode提供給客戶端。
劃重點劃重點,要考的!!!