根據(jù)下圖介紹HDFS的寫(xiě)入流程。
步驟
1. create
客戶(hù)端通過(guò)對(duì)DistributedFileSystem
對(duì)象調(diào)用create()
方法來(lái)發(fā)起創(chuàng)建文件流程娶桦。
2. create
DistributedFileSystem
對(duì)象對(duì)namenode
創(chuàng)建一個(gè)RPC調(diào)用暮胧,在文件系統(tǒng)中的命名空間中創(chuàng)建一個(gè)文件,此時(shí)還沒(méi)有對(duì)此文件創(chuàng)建相應(yīng)的數(shù)據(jù)塊。namenode
執(zhí)行各種檢查確保這個(gè)文件不存在以及客戶(hù)端有新建該文件的權(quán)限穴店。如果檢查通過(guò)namenode
就會(huì)創(chuàng)建這個(gè)文件并添加一條記錄。否則拿穴,文件創(chuàng)建失敗并向客戶(hù)端拋出IOException
異常泣洞。DistributedFileSystem
對(duì)象向客戶(hù)端返回一個(gè)FSDataOutputStream
對(duì)象。
3. write
客戶(hù)端獲得FSDataOutputStream
對(duì)象后默色,開(kāi)始寫(xiě)入數(shù)據(jù)球凰。和讀取數(shù)據(jù)一樣FSDataOutputStream
封裝了DFSOutputStream
對(duì)象,該對(duì)象負(fù)責(zé)處理datanode
和namenode
之間的通訊腿宰。
4. write packet
DFSOutputStream
將寫(xiě)入的數(shù)據(jù)分成一個(gè)個(gè)的數(shù)據(jù)包并寫(xiě)入內(nèi)部隊(duì)列呕诉,稱(chēng)為“數(shù)據(jù)隊(duì)列”。DataStreamer
處理數(shù)據(jù)隊(duì)列吃度,它的挑選出一組合適存儲(chǔ)數(shù)據(jù)的datanode
甩挫,namenode
根據(jù)這些信息來(lái)分配新的數(shù)據(jù)塊。假設(shè)副本數(shù)為3规肴,則寫(xiě)入需要涉及3個(gè)datanode
捶闸。DataStreamer
將數(shù)據(jù)包流式寫(xiě)入第一個(gè)datanode
中,并且第一個(gè)會(huì)將數(shù)據(jù)轉(zhuǎn)發(fā)給第二個(gè)datanode
拖刃。同樣删壮,第二個(gè)也會(huì)將數(shù)據(jù)轉(zhuǎn)發(fā)給第三個(gè)datanode
。
5. ack packet
DFSOutputStream
也維護(hù)著一個(gè)內(nèi)存數(shù)據(jù)包隊(duì)列來(lái)等待datanode
收到數(shù)據(jù)的確認(rèn)回執(zhí)兑牡,稱(chēng)為“確認(rèn)隊(duì)列”央碟。收到所有datanode
確認(rèn)信息后,該數(shù)據(jù)包才會(huì)從確認(rèn)隊(duì)列刪除。如果任何datanode
寫(xiě)入數(shù)據(jù)中發(fā)生故障亿虽,則執(zhí)行以下操作菱涤。
關(guān)閉錯(cuò)誤的寫(xiě)入流。確認(rèn)把隊(duì)列中的所有數(shù)據(jù)包都添加回?cái)?shù)據(jù)隊(duì)列的最前端洛勉,等待重新發(fā)送粘秆,確保故障發(fā)生節(jié)點(diǎn)以后的
datanode
不會(huì)漏掉任何一個(gè)數(shù)據(jù)包。當(dāng)前數(shù)據(jù)塊可能已經(jīng)正常寫(xiě)入一些節(jié)點(diǎn)收毫,則對(duì)這些數(shù)據(jù)塊指定一個(gè)新的標(biāo)識(shí)攻走,并將該表示傳遞給
namenode
,便于故障datanode
可以刪除存儲(chǔ)的部分?jǐn)?shù)據(jù)塊此再。刪除故障的
datanode
昔搂,選擇兩個(gè)正常的datanode
構(gòu)建一條新的管線。余下的數(shù)據(jù)塊寫(xiě)入管線中正常的datanode
输拇。namenode
注意到塊副本量不足時(shí)摘符,會(huì)在另一個(gè)節(jié)點(diǎn)上創(chuàng)建一個(gè)新的副本。
6. close
客戶(hù)端完成數(shù)據(jù)的寫(xiě)入后策吠,對(duì)數(shù)據(jù)流調(diào)用close()
方法逛裤。
7. complete
通知namenode
所有文件寫(xiě)入完成后完成寫(xiě)入操作。