Key Words: DistributedFileSystem, FSDataOutputStream, Pipeline, Coherency model
Hadoop 文件寫入

具體步驟如下:
1.客戶端通過對 DistributedFileSystem 對象調(diào)用 create() 來新建文件
2.DistributedFileSystem 對 namenode 創(chuàng)建一個 RPC 調(diào)用,在文件系統(tǒng)的命名空間中創(chuàng)建一個文件,盡管此時還沒有相應(yīng)的數(shù)據(jù)塊
namenode 執(zhí)行各種不同的檢查以確保這個文件不存在以及客戶端有新建該文件的權(quán)限。
DistributedFileSystem 向客戶端返回一個 FSDataOutputStream 對象(封裝了 DFSOutputStream)
3.客戶端寫入數(shù)據(jù),DFSOutputStream 將數(shù)據(jù)分割成一個個數(shù)據(jù)包,并寫入內(nèi)部隊列,稱為“數(shù)據(jù)隊列(data queue)”。DataStreamer 處理數(shù)據(jù)隊列,負(fù)責(zé)挑選出適合存儲數(shù)據(jù)副本的一組 datanode,并據(jù)此來要求 namenode 分配新的數(shù)據(jù)塊。
這一組 datanode 構(gòu)成一個管線(pipeline)
4.DataStreamer 將數(shù)據(jù)包流式傳輸?shù)焦芫€中的第 1 個 datanode,該 datanode 存儲數(shù)據(jù)包并將它發(fā)送到管線中的第 2 個 datanode。同樣,第 2 個 datanode 存儲該數(shù)據(jù)包并發(fā)送給管線中的第 3 個
5.DFSOutputStream 維護一個內(nèi)部數(shù)據(jù)包隊列等到 datanode 的收到確認(rèn)回執(zhí),稱為“確認(rèn)隊列(ack queue)”。收到管線中所有datanode 確認(rèn)信息后,該數(shù)據(jù)包才會從確認(rèn)隊列刪除
6.客戶端完成數(shù)據(jù)的寫入后,對數(shù)據(jù)流調(diào)用 close() 方法。該操作將剩余的所有數(shù)據(jù)包寫入 datanode 管線
7.在連接 namenode 來發(fā)送文件已經(jīng)完成的信號之前就等待確認(rèn)(waits for acknowledgments before contacting the namenode to signal that the file is complete),namenode 知道文件由哪些塊組成,所以它在返回成功前只需等待數(shù)據(jù)塊進行最小量的復(fù)制
異常情況
在數(shù)據(jù)被寫入的過程中,如果任何 datanode 損壞,將會有如下的一些動作,當(dāng)然這對于客戶端是透明的
1.首先管線被關(guān)閉,在確認(rèn)隊列(ack queue)中的數(shù)據(jù)包被添加到數(shù)據(jù)隊列(data queue),以至于下游的 datanodes 不會丟失任何數(shù)據(jù)包
2.當(dāng)前寫入失敗的數(shù)據(jù)包,在好的 datanodes 中添加一個標(biāo)識,通知 namenode,以便于寫入錯誤的 datanode 在稍后恢復(fù)時,其他的數(shù)據(jù)塊能夠被刪除
3.失敗的 datanode 從管線中被移除,新的管線從剩下的兩個好的 datanodes 中構(gòu)建
4.身下的塊數(shù)據(jù)被寫入管線中好的數(shù)據(jù)塊
5.namenode 注意到塊副本不足,會在其他的節(jié)點上安排一個副本
6.后續(xù)的數(shù)據(jù)塊接受正常的處理
副本安置策略(replica placement)
需要對可靠性、寫入帶寬和讀取帶寬進行權(quán)衡
hadoop 的默認(rèn)布局策略是在運行客戶端的節(jié)點上放置第一個副本(如果客戶端運行在集群之外,就隨機選擇一個節(jié)點,系統(tǒng)會避免挑選哪些存儲太慢或太忙的節(jié)點)。第二個副本放在與第一個不同且隨機選擇的機架中節(jié)點上(不同機架)。第三個副本與第二個副本放在同一個機架上,且隨機選擇另一個節(jié)點。其他部分放在急群眾隨機選擇的節(jié)點上,不過系統(tǒng)會盡量避免在同一個機架上放太多的副本
一旦選定副本的放置位置,就根據(jù)網(wǎng)絡(luò)拓?fù)鋭?chuàng)建一個管線,如下是副本數(shù)為 3 的管線示意圖

一致模型(Coherency model)
文件系統(tǒng)的一致模型描述了讀/寫的數(shù)據(jù)可見性。HDFS 為了性能犧牲了一些 Posix 要求,也就是默認(rèn)情況下,寫入文件的內(nèi)容并不保證能立即可見,及時數(shù)據(jù)流已經(jīng)刷新(調(diào)用 flush() 方法)并存儲。
當(dāng)寫入的數(shù)據(jù)超過一個塊后,第一個數(shù)據(jù)塊對新的 reader 可見。當(dāng)前正在寫入的塊對其他 reader 不可見
HDFS 提供了一種強行將所有緩存刷新到 datanode 中的手段,即調(diào)用 hflush() 方法。當(dāng) hflush() 方法返回成功后,對所有新的 reader 而言,HDFS 能保證文件中到目前為止寫入的數(shù)據(jù)均達到所有 datanode 的寫入管道并且對所有新的 reader 可見
hflush() 不保證數(shù)據(jù)寫入磁盤,為了確保數(shù)據(jù)寫入磁盤,可以使用 hsync()
選擇 hflush(), hsync() 合適的調(diào)用頻率
并行復(fù)制(distcp)
hadoop fs -cp 和 hadoop distcp 等效
注意 distcp 的主要參數(shù):
-overwrite:保持同樣的目錄結(jié)構(gòu)的同時強制覆蓋原有文件
-update:僅跟新發(fā)生變化的文件
-delete:可以刪除目標(biāo)路徑中任意沒在源路徑中出現(xiàn)的文件或目錄
-p:意味著文件狀態(tài)屬性如權(quán)限、塊大小和副本數(shù)被保留