使用HDFS提供的客戶端開發(fā)庫(kù)Client,向遠(yuǎn)程的Namenode發(fā)起RPC請(qǐng)求;
Namenode會(huì)檢查要?jiǎng)?chuàng)建的文件是否已經(jīng)存在,創(chuàng)建者是否有權(quán)限進(jìn)行操作,成功則會(huì)為文件 創(chuàng)建一個(gè)記錄,否則會(huì)讓客戶端拋出異常;
當(dāng)客戶端開始寫入文件的時(shí)候,會(huì)將文件切分成多個(gè)packets,并在內(nèi)部以數(shù)據(jù)隊(duì)列"data queue"的形式管理這些packets,并向Namenode申請(qǐng)新的blocks,獲取用來存儲(chǔ)replicas的合適的datanodes列表,列表的大小根據(jù)在Namenode中對(duì)replication的設(shè)置而定。
開始以pipeline(管道)的形式將packet寫入所有的replicas中。把packet以流的方式寫入第一個(gè)datanode,該datanode把該packet存儲(chǔ)之后,再將其傳遞給在此pipeline中的下一個(gè)datanode,直到最后一個(gè)datanode,這種寫數(shù)據(jù)的方式呈流水線的形式。
最后一個(gè)datanode成功存儲(chǔ)之后會(huì)返回一個(gè)ack packet,在pipeline里傳遞至客戶端,在客戶端的開發(fā)庫(kù)內(nèi)部維護(hù)著"ack queue",成功收到datanode返回的ack packet后會(huì)從"ack queue"移除相應(yīng)的packet。
如果傳輸過程中,有某個(gè)datanode出現(xiàn)了故障,那么當(dāng)前的pipeline會(huì)被關(guān)閉,出現(xiàn)故障的datanode會(huì)從當(dāng)前的pipeline中移除,剩余的block會(huì)繼續(xù)剩下的datanode中繼續(xù)以pipeline的形式傳輸,同時(shí)Namenode會(huì)分配一個(gè)新的datanode,保持replicas設(shè)定的數(shù)量。
當(dāng)客戶端向 HDFS 文件寫入數(shù)據(jù)的時(shí)候,一開始是寫到本地臨時(shí)文件中。假設(shè)該文件的副 本系數(shù)設(shè)置為 3 ,當(dāng)本地臨時(shí)文件累積到一個(gè)數(shù)據(jù)塊的大小時(shí),客戶端會(huì)從 Namenode 獲取一個(gè) Datanode 列表用于存放副本。然后客戶端開始向第一個(gè) Datanode 傳輸數(shù)據(jù),第一個(gè) Datanode 一小部分一小部分 (4 KB) 地接收數(shù)據(jù),將每一部分寫入本地倉(cāng)庫(kù),并同時(shí)傳輸該部分到列表中 第二個(gè) Datanode 節(jié)點(diǎn)。第二個(gè) Datanode 也是這樣,一小部分一小部分地接收數(shù)據(jù),寫入本地 倉(cāng)庫(kù),并同時(shí)傳給第三個(gè) Datanode 。最后,第三個(gè) Datanode 接收數(shù)據(jù)并存儲(chǔ)在本地。因此, Datanode 能流水線式地從前一個(gè)節(jié)點(diǎn)接收數(shù)據(jù),并在同時(shí)轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn),數(shù)據(jù)以流水線的 方式從前一個(gè) Datanode 復(fù)制到下一個(gè)