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

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

數(shù)據(jù)塊

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

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

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



























