HDFS全稱是Hadoop Distributed File System,是Hadoop項(xiàng)目中常見的一種 分布式文件系統(tǒng),在Hadoop項(xiàng)目中,HDFS解決了文件分布式存儲(chǔ)的問題。
HDFS有很多特點(diǎn):
① 保存多個(gè)副本,且提供容錯(cuò)機(jī)制,副本丟失或宕機(jī)自動(dòng)恢復(fù)。默認(rèn)存3份。
?、?運(yùn)行在廉價(jià)的機(jī)器上。
?、?適合大數(shù)據(jù)的處理。多大?多?。縃DFS默認(rèn)會(huì)將文件分割成block,64M為1個(gè)block,不足一64M的就以實(shí)際文件大小為block存在DataNode中。然后將block按鍵值對(duì)(形如:Block1: host2,host1,host3)存儲(chǔ)在HDFS上,并將鍵值對(duì)的映射存到NameNode的內(nèi)存中。一個(gè)鍵值對(duì)的映射大約為150個(gè)字節(jié)(如果存儲(chǔ)1億個(gè)文件,則NameNode需要20G空間),如果小文件太多,則會(huì)在NameNode中產(chǎn)生相應(yīng)多的鍵值對(duì)映射,那NameNode內(nèi)存的負(fù)擔(dān)會(huì)很重。而且處理大量小文件速度遠(yuǎn)遠(yuǎn)小于處理同等大小的大文件的速度。每一個(gè)小文件要占用一個(gè)slot,而task啟動(dòng)將耗費(fèi)大量時(shí)間甚至大部分時(shí)間都耗費(fèi)在啟動(dòng)task和釋放task上。
如上圖所示,HDFS也是按照Master和Slave的結(jié)構(gòu)。分NameNode、SecondaryNameNode、DataNode這幾個(gè)角色。
NameNode:是Master節(jié)點(diǎn),是HDFS的管理員。管理數(shù)據(jù)塊映射;處理客戶端的讀寫請(qǐng)求;負(fù)責(zé)維護(hù)元信息;配置副本策略;管理HDFS的名稱空間等
SecondaryNameNode:負(fù)責(zé)元信息和日志的合并;合并fsimage和fsedits然后再發(fā)給namenode。
PS:NameNode和SecondaryNameNode兩者沒有關(guān)系,更加不是備份,NameNode掛掉的時(shí)候SecondaryNameNode并不能頂替他的工作。
然而,由于NameNode單點(diǎn)問題,在Hadoop2中NameNode以集群的方式部署主要表現(xiàn)為HDFS Feration和HA,從而省去了SecondaryNode的存在,關(guān)于Hadoop2.x的改進(jìn)移步hadoop1.x 與hadoop2.x 架構(gòu)變化分析
DataNode:Slave節(jié)點(diǎn),奴隸,干活的。負(fù)責(zé)存儲(chǔ)client發(fā)來的數(shù)據(jù)塊block;執(zhí)行數(shù)據(jù)塊的讀寫操作。
熱備份:b是a的熱備份,如果a壞掉。那么b馬上運(yùn)行代替a的工作。
冷備份:b是a的冷備份,如果a壞掉。那么b不能馬上代替a工作。但是b上存儲(chǔ)a的一些信息,減少a壞掉之后的損失。
fsimage:元數(shù)據(jù)鏡像文件(文件系統(tǒng)的目錄樹。)是在NameNode啟動(dòng)時(shí)對(duì)整個(gè)文件系統(tǒng)的快照
edits:啟動(dòng)后NameNode對(duì)元數(shù)據(jù)的操作日志(針對(duì)文件系統(tǒng)做的修改操作記錄)
namenode內(nèi)存中存儲(chǔ)的是=fsimage+edits。
只有在NameNode重啟時(shí),edit logs才會(huì)合并到fsimage文件中,從而得到一個(gè)文件系統(tǒng)的最新快照。但是在產(chǎn)品集群中NameNode是很少重啟的,這也意味著當(dāng)NameNode運(yùn)行了很長時(shí)間后,edit logs文件會(huì)變得很大。在這種情況下就會(huì)出現(xiàn)下面一些問題:
edit logs文件會(huì)變的很大,怎么去管理這個(gè)文件是一個(gè)挑戰(zhàn)。
NameNode的重啟會(huì)花費(fèi)很長時(shí)間,因?yàn)橛泻芏嘣趀dit logs中的改動(dòng)要合并到fsimage文件上。
如果NameNode掛掉了,那我們就丟失了很多改動(dòng)因?yàn)榇藭r(shí)的fsimage文件非常舊。[筆者認(rèn)為在這個(gè)情況下丟失的改動(dòng)不會(huì)很多, 因?yàn)閬G失的改動(dòng)應(yīng)該是還在內(nèi)存中但是沒有寫到edit logs的這部分。]
那么其實(shí)可以在NameNode中起一個(gè)程序定時(shí)進(jìn)行新的fsimage=edits+fsimage的更新,但是有一個(gè)更好的方法是SecondaryNameNode。
SecondaryNameNode的職責(zé)是合并NameNode的edit logs到fsimage文件中,減少NameNode下一次重啟過程
上面的圖片展示了Secondary NameNode是怎么工作的。
首先,它定時(shí)到NameNode去獲取edit logs,并更新到自己的fsimage上。
一旦它有了新的fsimage文件,它將其拷貝回NameNode中。
NameNode在下次重啟時(shí)會(huì)使用這個(gè)新的fsimage文件,從而減少重啟的時(shí)間。
Secondary NameNode的整個(gè)目的是在HDFS中提供一個(gè)檢查點(diǎn)。它只是NameNode的一個(gè)助手節(jié)點(diǎn)。這也是它在社區(qū)內(nèi)被認(rèn)為是檢查點(diǎn)節(jié)點(diǎn)的原因。SecondaryNameNode負(fù)責(zé)定時(shí)默認(rèn)1小時(shí),從namenode上,獲取fsimage和edits來進(jìn)行合并,然后再發(fā)送給namenode。減少namenode的工作量和下一次重啟過程。
工作原理
寫操作:
有一個(gè)文件FileA,100M大小。Client將FileA寫入到HDFS上。
HDFS按默認(rèn)配置。
HDFS分布在三個(gè)機(jī)架上Rack1,Rack2,Rack3。
a. Client將FileA按64M分塊。分成兩塊,block1和Block2;
b. Client向nameNode發(fā)送寫數(shù)據(jù)請(qǐng)求,如圖藍(lán)色虛線①------》。
c. NameNode節(jié)點(diǎn),記錄block信息(即鍵值對(duì)的映射)。并返回可用的DataNode,如粉色虛線②------》。
Block1: host2,host1,host3
Block2: host7,host8,host4
原理:
NameNode具有RackAware機(jī)架感知功能,這個(gè)可以配置。
若client為DataNode節(jié)點(diǎn),那存儲(chǔ)block時(shí),規(guī)則為:副本1,同client的節(jié)點(diǎn)上;副本2,不同機(jī)架節(jié)點(diǎn)上;副本3,同第二個(gè)副本機(jī)架的另一個(gè)節(jié)點(diǎn)上;其他副本隨機(jī)挑選。
若client不為DataNode節(jié)點(diǎn),那存儲(chǔ)block時(shí),規(guī)則為:副本1,隨機(jī)選擇一個(gè)節(jié)點(diǎn)上;副本2,不同副本1,機(jī)架上;副本3,同副本2相同的另一個(gè)節(jié)點(diǎn)上;其他副本隨機(jī)挑選。
d. client向DataNode發(fā)送block1;發(fā)送過程是以流式寫入。
流式寫入過程,
1》將64M的block1按64k的package劃分;
2》然后將第一個(gè)package發(fā)送給host2;
3》host2接收完后,將第一個(gè)package發(fā)送給host1,同時(shí)client想host2發(fā)送第二個(gè)package;
4》host1接收完第一個(gè)package后,發(fā)送給host3,同時(shí)接收host2發(fā)來的第二個(gè)package。
5》以此類推,如圖紅線實(shí)線所示,直到將block1發(fā)送完畢。
6》host2,host1,host3向NameNode,host2向Client發(fā)送通知,說“消息發(fā)送完了”。如圖粉紅顏色實(shí)線所示。
7》client收到host2發(fā)來的消息后,向namenode發(fā)送消息,說我寫完了。這樣就真完成了。如圖黃色粗實(shí)線
8》發(fā)送完block1后,再向host7,host8,host4發(fā)送block2,如圖藍(lán)色實(shí)線所示。
9》發(fā)送完block2后,host7,host8,host4向NameNode,host7向Client發(fā)送通知,如圖淺綠色實(shí)線所示。
10》client向NameNode發(fā)送消息,說我寫完了,如圖黃色粗實(shí)線。。。這樣就完畢了。
分析,通過寫過程,我們可以了解到:
?、賹?T文件,我們需要3T的存儲(chǔ),3T的網(wǎng)絡(luò)流量帶寬。
②在執(zhí)行讀或?qū)懙倪^程中,NameNode和DataNode通過HeartBeat進(jìn)行保存通信,確定DataNode活著。如果發(fā)現(xiàn)DataNode死掉了,就將死掉的DataNode上的數(shù)據(jù),放到其他節(jié)點(diǎn)去。讀取時(shí),要讀其他節(jié)點(diǎn)去。
?、蹝斓粢粋€(gè)節(jié)點(diǎn),沒關(guān)系,還有其他節(jié)點(diǎn)可以備份;甚至,掛掉某一個(gè)機(jī)架,也沒關(guān)系;其他機(jī)架上,也有備份。
讀操作:
讀操作就簡單一些了,如圖所示,client要從datanode上,讀取FileA。而FileA由block1和block2組成。
那么,讀操作流程為:
a. client向namenode發(fā)送讀請(qǐng)求。
b. namenode查看Metadata信息(鍵值對(duì)的映射),返回fileA的block的位置。
block1:host2,host1,host3
block2:host7,host8,host4
c. block的位置是有先后順序的,先讀block1,再讀block2。而且block1去host2上讀取;然后block2,去host7上讀取;
上面例子中,client位于機(jī)架外,那么如果client位于機(jī)架內(nèi)某個(gè)DataNode上,例如,client是host6。那么讀取的時(shí)候,遵循的規(guī)律是:
優(yōu)先讀取本機(jī)架上的數(shù)據(jù)。
HDFS中常用到的命令
3、hadoop fsck
4、start-balancer.sh
注意,看了hdfs的布局,以及作用,這里需要考慮幾個(gè)問題:
1、既然NameNode,存儲(chǔ)小文件不太合適,那小文件如何處理?
至少有兩種場(chǎng)景下會(huì)產(chǎn)生大量的小文件:
(1)這些小文件都是一個(gè)大邏輯文件的一部分。由于HDFS在2.x版本開始支持對(duì)文件的append,所以在此之前保存無邊界文件(例如,log文件)(譯者注:持續(xù)產(chǎn)生的文件,例如日志每天都會(huì)生成)一種常用的方式就是將這些數(shù)據(jù)以塊的形式寫入HDFS中(a very common pattern for saving unbounded files (e.g. log files) is to write them in chunks into HDFS)。
(2)文件本身就是很小。設(shè)想一下,我們有一個(gè)很大的圖片語料庫,每一個(gè)圖片都是一個(gè)獨(dú)一的文件,并且沒有一種很好的方法來將這些文件合并為一個(gè)大的文件。
?。?)第一種情況
對(duì)于第一種情況,文件是許多記錄(Records)組成的,那么可以通過調(diào)用HDFS的sync()方法(和append方法結(jié)合使用),每隔一定時(shí)間生成一個(gè)大文件?;蛘撸梢酝ㄟ^寫一個(gè)程序來來合并這些小文件(可以看一下Nathan Marz關(guān)于Consolidator一種小工具的文章)。
?。?)第二種情況
對(duì)于第二種情況,就需要某種形式的容器通過某種方式來對(duì)這些文件進(jìn)行分組。Hadoop提供了一些選擇:
HAR File
Hadoop Archives (HAR files)是在0.18.0版本中引入到HDFS中的,它的出現(xiàn)就是為了緩解大量小文件消耗NameNode內(nèi)存的問題。HAR文件是通過在HDFS上構(gòu)建一個(gè)分層文件系統(tǒng)來工作。HAR文件通過hadoop archive命令來創(chuàng)建,而這個(gè)命令實(shí) 際上是運(yùn)行了一個(gè)MapReduce作業(yè)來將小文件打包成少量的HDFS文件(譯者注:將小文件進(jìn)行合并幾個(gè)大文件)。對(duì)于client端來說,使用HAR文件沒有任何的改變:所有的原始文件都可見以及可訪問(只是使用har://URL,而不是hdfs://URL),但是在HDFS中中文件數(shù)卻減少了。
讀取HAR中的文件不如讀取HDFS中的文件更有效,并且實(shí)際上可能較慢,因?yàn)槊總€(gè)HAR文件訪問需要讀取兩個(gè)索引文件以及還要讀取數(shù)據(jù)文件本身(如下圖)。盡管HAR文件可以用作MapReduce的輸入,但是沒有特殊的魔法允許MapReduce直接操作HAR在HDFS塊上的所有文件(although HAR files can be used as input to MapReduce, there is no special magic that allows maps to operate over all the files in the HAR co-resident on a HDFS block)。 可以考慮通過創(chuàng)建一種input format,充分利用HAR文件的局部性優(yōu)勢(shì),但是目前還沒有這種input format。需要注意的是:MultiFileInputSplit,即使在HADOOP-4565的改進(jìn),但始終還是需要每個(gè)小文件的尋找。我們非常有興趣看到這個(gè)與SequenceFile進(jìn)行對(duì)比。 在目前看來,HARs可能最好僅用于存儲(chǔ)文檔(At the current time HARs are probably best used purely for archival purposes.)
評(píng)論
查看更多