
Client將FileA按64M分塊。分成兩塊,block1和Block2;
Client向nameNode發(fā)送寫數(shù)據(jù)請求,如圖藍(lán)色虛線①------>
NameNode節(jié)點,記錄block信息。并返回可用的DataNode ( NameNode按什么規(guī)則返回DataNode? 參見第三單 hadoop機架感知 ),如粉色虛線②--------->
Block1: host2,host1,host3
Block2: host7,host8,host4
client向DataNode發(fā)送block1;發(fā)送過程是以流式寫入,流式寫入過程如下:
將64M的block1按64k的packet劃分
然后將第一個packet發(fā)送給host2
host2接收完后,將第一個packet發(fā)送給host1,同時client想host2發(fā)送第二個packet
host1接收完第一個packet后,發(fā)送給host3,同時接收host2發(fā)來的第二個packet
以此類推,如圖紅線實線所示,直到將block1發(fā)送完畢
host2,host1,host3向NameNode,host2向Client發(fā)送通知,說“消息發(fā)送完了”。如圖粉紅顏色實線所示
client收到host2發(fā)來的消息后,向namenode發(fā)送消息,說我寫完了。這樣就真完成了。如圖黃色粗實線
發(fā)送完block1后,再向host7,host8,host4發(fā)送block2,如圖藍(lán)色實線所示
說明:

小結(jié):
寫入的過程,按hdsf默認(rèn)設(shè)置, 1T文件,我們需要3T的存儲 , 3T的網(wǎng)絡(luò)流量
在執(zhí)行讀或?qū)懙倪^程中,NameNode和DataNode通過HeartBeat進(jìn)行保存通信,確定DataNode活著。如果發(fā)現(xiàn)DataNode死掉了,就將死掉的DataNode上的數(shù)據(jù),放到其他節(jié)點去。讀取時,要讀其他節(jié)點去
掛掉一個節(jié)點,沒關(guān)系,還有其他節(jié)點可以備份;甚至,掛掉某一個機架,也沒關(guān)系;其他機架上,也有備份
hdfs讀文件:
讀到文件示意圖如下:

客戶端通過調(diào)用FileSystem對象的open()方法來打開希望讀取的文件,對于HDFS來說,這個對象時分布文件系統(tǒng)的一個實例;
DistributedFileSystem通過使用RPC來調(diào)用NameNode以確定文件起始塊的位置,同一Block按照重復(fù)數(shù)會返回多個位置,這些位置按照 Hadoop集群拓?fù)浣Y(jié)構(gòu)排序,距離客戶端近的排在前 面 ( 詳見第三章 )
前兩步會返回一個FSDataInputStream對象,該對象會被封裝成DFSInputStream對象,DFSInputStream可以方便的管理datanode和namenode數(shù)據(jù)流,客戶端對這個輸入流調(diào)用read()方法
存儲著文件起始塊的DataNode地址的DFSInputStream隨即連接距離最近的DataNode,通過對數(shù)據(jù)流反復(fù)調(diào)用read()方法,將數(shù)據(jù)從DataNode傳輸?shù)娇蛻舳?/p>
到達(dá)塊的末端時,DFSInputStream會關(guān)閉與該DataNode的連接,然后尋找下一個塊的最佳DataNode,這些操作對客戶端來說是透明的,客戶端的角度看來只是讀一個持續(xù)不斷的流
一旦客戶端完成讀取,就對FSDataInputStream調(diào)用close()方法關(guān)閉文件讀取
block持續(xù)化結(jié)構(gòu):
DataNode節(jié)點上一個Block持久化到磁盤上的物理存儲結(jié)構(gòu),如下圖所示:

每個Block文件(如上圖中blk_1084013198文件)都對應(yīng)一個meta文件(如上圖中blk_1084013198_10273532.meta文件), Block文件是一個一個Chunk的二進(jìn)制數(shù)據(jù) (每個Chunk的大小是512字節(jié)),而meta文件是與 每一個Chunk對應(yīng)的Checksum數(shù)據(jù) ,是序列化形式存儲