簡述
HDFS(Hadoop Distributed File System),作為Google File System(GFS)的實(shí)現(xiàn),是Hadoop項(xiàng)目的核心子項(xiàng)目,是分布式計(jì)算中數(shù)據(jù)存儲(chǔ)管理的基礎(chǔ),是基于流數(shù)據(jù)模式訪問和處理超大文件的需求而開發(fā)的,可以運(yùn)行于廉價(jià)的商用服務(wù)器上。它所具有的高容錯(cuò)、高可靠性、高可擴(kuò)展性、高獲得性、高吞吐率等特征為海量數(shù)據(jù)提供了不怕故障的存儲(chǔ),為超大數(shù)據(jù)集(Large Data Set)的應(yīng)用處理帶來了很多便利。
適用、不適用的場景
HDFS特點(diǎn):
- 高容錯(cuò)性、可構(gòu)建在廉價(jià)機(jī)器上
- 適合批處理
- 適合大數(shù)據(jù)處理
- 流式文件訪問
HDFS局限:
- 不支持低延遲訪問
- 不適合小文件存儲(chǔ)
- 不支持并發(fā)寫入
- 不支持修改
HDFS架構(gòu)
看兩張HDFS的架構(gòu)圖。


HDFS由四部分組成,HDFS Client、NameNode、DataNode和Secondary NameNode。
HDFS是一個(gè)主/從(Mater/Slave)體系結(jié)構(gòu),HDFS集群擁有一個(gè)NameNode和一些DataNode。NameNode管理文件系統(tǒng)的元數(shù)據(jù),DataNode存儲(chǔ)實(shí)際的數(shù)據(jù)。
HDFS客戶端:就是客戶端。
1、提供一些命令來管理、訪問 HDFS,比如啟動(dòng)或者關(guān)閉HDFS。
2、與 DataNode 交互,讀取或者寫入數(shù)據(jù);讀取時(shí),要與 NameNode 交互,獲取文件的位置信息;寫入 HDFS 的時(shí)候,Client 將文件切分成 一個(gè)一個(gè)的Block,然后進(jìn)行存儲(chǔ)。
NameNode:即Master,
1、管理 HDFS 的名稱空間。
2、管理數(shù)據(jù)塊(Block)映射信息
3、配置副本策略
4、處理客戶端讀寫請(qǐng)求。
DataNode:就是Slave。NameNode 下達(dá)命令,DataNode 執(zhí)行實(shí)際的操作。
1、存儲(chǔ)實(shí)際的數(shù)據(jù)塊。
2、執(zhí)行數(shù)據(jù)塊的讀/寫操作。
Secondary NameNode:并非 NameNode 的熱備。當(dāng)NameNode 掛掉的時(shí)候,它并不能馬上替換 NameNode 并提供服務(wù)。
1、輔助 NameNode,分擔(dān)其工作量。
2、定期合并 fsimage和fsedits,并推送給NameNode。
3、在緊急情況下,可輔助恢復(fù) NameNode。
讀、寫文件過程
從HDFS讀取內(nèi)容
1、首先調(diào)用DistributedFileSystem對(duì)象的open方法,其實(shí)獲取的是一個(gè)DistributedFileSystem的實(shí)例。
2、DistributedFileSystem通過RPC(遠(yuǎn)程過程調(diào)用)獲得文件的第一批block的locations,同一block按照重復(fù)數(shù)會(huì)返回多個(gè)locations,這些locations按照hadoop拓?fù)浣Y(jié)構(gòu)排序,距離客戶端近的排在前面。
3、前兩步會(huì)返回一個(gè)FSDataInputStream對(duì)象,該對(duì)象會(huì)被封裝成 DFSInputStream 對(duì)象,DFSInputStream可以方便的管理DataNode和NameNode數(shù)據(jù)流??蛻舳苏{(diào)用read方法,DFSInputStream就會(huì)找出離客戶端最近的DataNode并連接DataNode。
4、數(shù)據(jù)從DataNode源源不斷的流向客戶端。
5、如果第一個(gè)block塊的數(shù)據(jù)讀完了,就會(huì)關(guān)閉指向第一個(gè)block塊的DataNode連接,接著讀取下一個(gè)block塊。這些操作對(duì)客戶端來說是透明的,從客戶端的角度來看只是讀一個(gè)持續(xù)不斷的流。
6、如果第一批block都讀完了,DFSInputStream就會(huì)去NameNode拿下一批blocks的location,然后繼續(xù)讀,如果所有的block塊都讀完,這時(shí)就會(huì)關(guān)閉掉所有的流。

向HDFS寫入內(nèi)容
1.客戶端通過調(diào)用DistributedFileSystem的create方法,創(chuàng)建一個(gè)新的文件。
2.DistributedFileSystem通過RPC(遠(yuǎn)程過程調(diào)用)調(diào)用NameNode,去創(chuàng)建一個(gè)沒有blocks關(guān)聯(lián)的新文件。創(chuàng)建前,NameNode會(huì)做各種校驗(yàn),比如文件是否存在,客戶端有無權(quán)限去創(chuàng)建等。如果校驗(yàn)通過,NameNode 就會(huì)記錄下新文件,否則就會(huì)拋出IO異常。
3.前兩步結(jié)束后會(huì)返回 FSDataOutputStream 的對(duì)象,和讀文件的時(shí)候相似,F(xiàn)SDataOutputStream 被封裝成 DFSOutputStream,DFSOutputStream 可以協(xié)調(diào)NameNode和 DataNode??蛻舳碎_始寫數(shù)據(jù)到DFSOutputStream,DFSOutputStream會(huì)把數(shù)據(jù)切成一個(gè)個(gè)小packet,然后排成隊(duì)列data queue。
4.DataStreamer 會(huì)去處理接受 data queue,它先問詢 NameNode 這個(gè)新的 block 最適合存儲(chǔ)的在哪幾個(gè)DataNode里,比如重復(fù)數(shù)是3,那么就找到3個(gè)最適合的DataNode,把它們排成一個(gè) pipeline。DataStreamer 把 packet 按隊(duì)列輸出到管道的第一個(gè) DataNode 中,第一個(gè) DataNode又把 packet 輸出到第二個(gè) DataNode 中,以此類推。
5.DFSOutputStream 還有一個(gè)隊(duì)列叫 ack queue,也是由 packet 組成,等待DataNode的收到響應(yīng),當(dāng)pipeline中的所有DataNode都表示已經(jīng)收到的時(shí)候,這時(shí)akc queue才會(huì)把對(duì)應(yīng)的packet包移除掉。
6.客戶端完成寫數(shù)據(jù)后,調(diào)用close方法關(guān)閉寫入流。
7.DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一個(gè)ack 后,通知 DataNode 把文件標(biāo)示為已完成。

副本存放策略
一般情況下副本系數(shù)為3,HDFS的副本放置策略是:將第一個(gè)副本放在本地節(jié)點(diǎn),將第二個(gè)副本放在本地機(jī)架上的另一個(gè)節(jié)點(diǎn),而第三個(gè)副本放到不同機(jī)架上的節(jié)點(diǎn)。
這種方式減少了機(jī)架間的寫流量,從而提高了寫的性能。機(jī)架故障的機(jī)率遠(yuǎn)小于節(jié)點(diǎn)故障。這種方式并不影響數(shù)據(jù)可靠性和可用性的限制,并且它確實(shí)減少了讀操作的網(wǎng)絡(luò)聚合帶寬,因?yàn)槲募K僅存在兩個(gè)不同的機(jī)架,而不是三個(gè)。
文件的副本不是均勻的分布在機(jī)架當(dāng)中,1/3的副本在同一個(gè)節(jié)點(diǎn)上,1/3副本在同一個(gè)機(jī)架上,另外1/3個(gè)副本均勻地分布在其他機(jī)架上。
流水線復(fù)制
假設(shè)HDFS副本系數(shù)為3,當(dāng)本地暫時(shí)文件積累到一個(gè)數(shù)據(jù)塊大小時(shí),client會(huì)從NameNode獲取一個(gè)列表用于存放副本。然后client開始向第一個(gè)DataNode數(shù)據(jù)傳輸,第一個(gè)DataNode一小部分一小部分地接收數(shù)據(jù),將每一部分寫入本地倉庫,并同一時(shí)間傳輸該部分到列表中的第二個(gè)DataNode節(jié)點(diǎn)。第二個(gè)DataNode也是這樣,一小部分一小部分地接收數(shù)據(jù),寫入本地倉庫,并同一時(shí)候轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn),數(shù)據(jù)以流水線的方式從前一個(gè)DataNode拷貝到下一個(gè)DataNode。最后,第三個(gè)DataNode接收數(shù)據(jù)并存儲(chǔ)到本地。因此,DataNode能流水線地從前一個(gè)節(jié)點(diǎn)接收數(shù)據(jù),并同一時(shí)間轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn),數(shù)據(jù)以流水線的方式從前一個(gè)DataNode拷貝到下一個(gè)DataNode,并以相反的方向Ack前一個(gè)Node。
擴(kuò)展:大數(shù)據(jù)存儲(chǔ)生態(tài)圈簡介
Hive與Hbase的數(shù)據(jù)一般都存儲(chǔ)在HDFS上。HDFS為他們提供了高可靠性的底層存儲(chǔ)支持。
Hive
Hive不支持更改數(shù)據(jù)的操作,Hive基于數(shù)據(jù)倉庫,提供靜態(tài)數(shù)據(jù)的動(dòng)態(tài)查詢。其使用類SQL語言,底層經(jīng)過編譯轉(zhuǎn)為MapReduce程序,在Hadoop上運(yùn)行,數(shù)據(jù)存儲(chǔ)在HDFS上。
HBase
Hbase是Hadoop database,即Hadoop數(shù)據(jù)庫。它是一個(gè)適合于非結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)庫,HBase基于列的而不是基于行的模式。
HBase是Google Bigtable的開源實(shí)現(xiàn),類似Google Bigtable利用GFS作為其文件存儲(chǔ)系統(tǒng),HBase利用HDFS作為其文件存儲(chǔ)系統(tǒng);Google運(yùn)行MapReduce來處理Bigtable中的海量數(shù)據(jù),HBase同樣利用Hadoop MapReduce來處理HBase中的海量數(shù)據(jù)。
擴(kuò)展:GFS簡介(Google File System)
GFS、MapReduce、BigTable是Google大數(shù)據(jù)的三大理論。我們簡單描述下GFS:
- 文件被分為許多固定大小的chunk,并分配一個(gè)全局唯一的64位Chunk標(biāo)志;
- Master-Slave結(jié)構(gòu),Master節(jié)點(diǎn)記錄節(jié)點(diǎn)及Chunk元信息;
- 為了保證可靠性,每個(gè)Chunk會(huì)被復(fù)制到多個(gè)Slave節(jié)點(diǎn)上;
- HDFS保證了CAP的CP,它的一致性如何實(shí)現(xiàn)的可以參考文末的引用文獻(xiàn)。
參考文章:
https://blog.csdn.net/luoyhang003/article/details/72229121(GFS介紹)
https://blog.csdn.net/qiaojialin/article/details/71574203(GFS一致性總結(jié))
https://blog.csdn.net/wypersist/article/details/79757242(HDFS核心技術(shù)詳解)
https://blog.csdn.net/w1573007/article/details/52966742(Google三大理論)