分布式文件系統(tǒng)HDFS解析
Hadoop 主要由HDFS和MapReduce 引擎兩部分組成。最底部是HDFS,它存儲(chǔ)Hadoop 集群中所有存儲(chǔ)節(jié)點(diǎn)上的文件。HDFS 的上一層是MapReduce 引擎,該引擎由JobTrackers 和TaskTrackers組成。
一、HDFS基本概念
1、數(shù)據(jù)塊
HDFS默認(rèn)的最基本的存儲(chǔ)單位是64M的數(shù)據(jù)塊,這個(gè)數(shù)據(jù)塊可以理解和一般的文件里面的分塊是一樣的,不同于普通文件系統(tǒng)的是,HDFS中,如果一個(gè)文件小于一個(gè)數(shù)據(jù)塊的大小,那么并不占用整個(gè)數(shù)據(jù)塊存儲(chǔ)空間。
2、元數(shù)據(jù)節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)
元數(shù)據(jù)節(jié)點(diǎn)是用來管理文件系統(tǒng)的命名空間,它將所有的文件和文件夾的元數(shù)據(jù)保存在一個(gè)文件系統(tǒng)樹中。 數(shù)據(jù)節(jié)點(diǎn)是用來存儲(chǔ)數(shù)據(jù)文件的。 從元數(shù)據(jù)節(jié)點(diǎn)(secondarynamenode)不是我們所想象的元數(shù)據(jù)節(jié)點(diǎn)的備用節(jié)點(diǎn),其實(shí)它主要的功能是主要功能就是周期性將元數(shù)據(jù)節(jié)點(diǎn)的命名空間鏡像文件和修改日志合并,以防日志文件過大。
3、HDFS中的數(shù)據(jù)流
讀文件
客戶端(client)用FileSystem的open()函數(shù)打開文件,DistributedFileSystem用RPC調(diào)用元數(shù)據(jù)節(jié)點(diǎn),得到文件的數(shù)據(jù)塊信息。對(duì)于每一個(gè)數(shù)據(jù)塊,元數(shù)據(jù)節(jié)點(diǎn)返回保存數(shù)據(jù)塊的數(shù)據(jù)節(jié)點(diǎn)的地址。DistributedFileSystem返回FSDataInputStream給客戶端,用來讀取數(shù)據(jù)??蛻舳苏{(diào)用stream的read()函數(shù)開始讀取數(shù)據(jù)。DFSInputStream連接保存此文件第一個(gè)數(shù)據(jù)塊的最近的數(shù)據(jù)節(jié)點(diǎn)。Data從數(shù)據(jù)節(jié)點(diǎn)讀到客戶端(client),當(dāng)此數(shù)據(jù)塊讀取完畢時(shí),DFSInputStream關(guān)閉和此數(shù)據(jù)節(jié)點(diǎn)的連接,然后連接此文件下一個(gè)數(shù)據(jù)塊的最近的數(shù)據(jù)節(jié)點(diǎn)。當(dāng)客戶端讀取完畢數(shù)據(jù)的時(shí)候,調(diào)用FSDataInputStream的close函數(shù)。
整個(gè)過程如圖所示:

寫文件
客戶端調(diào)用create()來創(chuàng)建文件,DistributedFileSystem用RPC調(diào)用元數(shù)據(jù)節(jié)點(diǎn),在文件系統(tǒng)的命名空間中創(chuàng)建一個(gè)新的文件。元數(shù)據(jù)節(jié)點(diǎn)首先確定文件原來不存在,并且客戶端有創(chuàng)建文件的權(quán)限,然后創(chuàng)建新文件。DistributedFileSystem返回DFSOutputStream,客戶端用于寫數(shù)據(jù)??蛻舳碎_始寫入數(shù)據(jù),DFSOutputStream將數(shù)據(jù)分成塊,寫入data queue。Data queue由Data Streamer讀取,并通知元數(shù)據(jù)節(jié)點(diǎn)分配數(shù)據(jù)節(jié)點(diǎn),用來存儲(chǔ)數(shù)據(jù)塊(每塊默認(rèn)復(fù)制3塊)。分配的數(shù)據(jù)節(jié)點(diǎn)放在一個(gè)pipeline里。Data Streamer將數(shù)據(jù)塊寫入pipeline中的第一個(gè)數(shù)據(jù)節(jié)點(diǎn)。第一個(gè)數(shù)據(jù)節(jié)點(diǎn)將數(shù)據(jù)塊發(fā)送給第二個(gè)數(shù)據(jù)節(jié)點(diǎn)。第二個(gè)數(shù)據(jù)節(jié)點(diǎn)將數(shù)據(jù)發(fā)送給第三個(gè)數(shù)據(jù)節(jié)點(diǎn)。DFSOutputStream為發(fā)出去的數(shù)據(jù)塊保存了ack queue,等待pipeline中的數(shù)據(jù)節(jié)點(diǎn)告知數(shù)據(jù)已經(jīng)寫入成功。如果數(shù)據(jù)節(jié)點(diǎn)在寫入的過程中失敗:關(guān)閉pipeline,將ack queue中的數(shù)據(jù)塊放入data queue的開始。
整個(gè)過程如圖所示:

二、HDFS的優(yōu)缺點(diǎn)
2.1 HDFS的優(yōu)點(diǎn)
1)處理超大文件
這里的超大文件通常是指百M(fèi)B、設(shè)置數(shù)百TB大小的文件。目前在實(shí)際應(yīng)用中,HDFS已經(jīng)能用來存儲(chǔ)管理PB級(jí)的數(shù)據(jù)了。
2)流式的訪問數(shù)據(jù)
HDFS的設(shè)計(jì)建立在更多地響應(yīng)"一次寫入、多次讀寫"任務(wù)的基礎(chǔ)上。這意味著一個(gè)數(shù)據(jù)集一旦由數(shù)據(jù)源生成,就會(huì)被復(fù)制分發(fā)到不同的存儲(chǔ)節(jié)點(diǎn)中,然后響應(yīng)各種各樣的數(shù)據(jù)分析任務(wù)請(qǐng)求。在多數(shù)情況下,分析任務(wù)都會(huì)涉及數(shù)據(jù)集中的大部分?jǐn)?shù)據(jù),也就是說,對(duì)HDFS來說,請(qǐng)求讀取整個(gè)數(shù)據(jù)集要比讀取一條記錄更加高效。
3)運(yùn)行于廉價(jià)的商用機(jī)器集群上
Hadoop設(shè)計(jì)對(duì)硬件需求比較低,只須運(yùn)行在低廉的商用硬件集群上,而無需昂貴的高可用性機(jī)器上。廉價(jià)的商用機(jī)也就意味著大型集群中出現(xiàn)節(jié)點(diǎn)故障情況的概率非常高。這就要求設(shè)計(jì)HDFS時(shí)要充分考慮數(shù)據(jù)的可靠性,安全性及高可用性。
2.2 HDFS的缺點(diǎn)
1)不適合低延遲數(shù)據(jù)訪問
如果要處理一些用戶要求時(shí)間比較短的低延遲應(yīng)用請(qǐng)求,則HDFS不適合。HDFS是為了處理大型數(shù)據(jù)集分析任務(wù)的,主要是為達(dá)到高的數(shù)據(jù)吞吐量而設(shè)計(jì)的,這就可能要求以高延遲作為代價(jià)。
改進(jìn)策略:對(duì)于那些有低延時(shí)要求的應(yīng)用程序,HBase是一個(gè)更好的選擇。通過上層數(shù)據(jù)管理項(xiàng)目來盡可能地彌補(bǔ)這個(gè)不足。在性能上有了很大的提升,它的口號(hào)就是goes real time。使用緩存或多master設(shè)計(jì)可以降低client的數(shù)據(jù)請(qǐng)求壓力,以減少延時(shí)。還有就是對(duì)HDFS系統(tǒng)內(nèi)部的修改,這就得權(quán)衡大吞吐量與低延時(shí)了,HDFS不是萬能的銀彈。
2)無法高效存儲(chǔ)大量小文件
因?yàn)镹amenode把文件系統(tǒng)的元數(shù)據(jù)放置在內(nèi)存中,所以文件系統(tǒng)所能容納的文件數(shù)目是由Namenode的內(nèi)存大小來決定。一般來說,每一個(gè)文件、文件夾和Block需要占據(jù)150字節(jié)左右的空間,所以,如果你有100萬個(gè)文件,每一個(gè)占據(jù)一個(gè)Block,你就至少需要300MB內(nèi)存。當(dāng)前來說,數(shù)百萬的文件還是可行的,當(dāng)擴(kuò)展到數(shù)十億時(shí),對(duì)于當(dāng)前的硬件水平來說就沒法實(shí)現(xiàn)了。還有一個(gè)問題就是,因?yàn)镸ap task的數(shù)量是由splits來決定的,所以用MR處理大量的小文件時(shí),就會(huì)產(chǎn)生過多的Maptask,線程管理開銷將會(huì)增加作業(yè)時(shí)間。舉個(gè)例子,處理10000M的文件,若每個(gè)split為1M,那就會(huì)有10000個(gè)Maptasks,會(huì)有很大的線程開銷;若每個(gè)split為100M,則只有100個(gè)Maptasks,每個(gè)Maptask將會(huì)有更多的事情做,而線程的管理開銷也將減小很多。
改進(jìn)策略:要想讓HDFS能處理好小文件,有不少方法。
利用SequenceFile、MapFile、Har等方式歸檔小文件,這個(gè)方法的原理就是把小文件歸檔起來管理,HBase就是基于此的。對(duì)于這種方法,如果想找回原來的小文件內(nèi)容,那就必須得知道與歸檔文件的映射關(guān)系。
橫向擴(kuò)展,一個(gè)Hadoop集群能管理的小文件有限,那就把幾個(gè)Hadoop集群拖在一個(gè)虛擬服務(wù)器后面,形成一個(gè)大的Hadoop集群。google也是這么干過的。
多Master設(shè)計(jì),這個(gè)作用顯而易見了。正在研發(fā)中的GFS II也要改為分布式多Master設(shè)計(jì),還支持Master的Failover,而且Block大小改為1M,有意要調(diào)優(yōu)處理小文件啊。
附帶個(gè)Alibaba DFS的設(shè)計(jì),也是多Master設(shè)計(jì),它把Metadata的映射存儲(chǔ)和管理分開了,由多個(gè)Metadata存儲(chǔ)節(jié)點(diǎn)和一個(gè)查詢Master節(jié)點(diǎn)組成。
3)不支持多用戶寫入及任意修改文件
在HDFS的一個(gè)文件中只有一個(gè)寫入者,而且寫操作只能在文件末尾完成,即只能執(zhí)行追加操作。目前HDFS還不支持多個(gè)用戶對(duì)同一文件的寫操作,以及在文件任意位置進(jìn)行修改。