1.5.5 HDFS讀寫解析 1.5.5.1 HDFS讀數據流程 客戶端通過Distributed FileSystem向NameNode請求下載文件,NameNode通過查詢元數據, 找到文件塊所在的DataNode地址。 挑選一臺DataNode(就近原則,然後隨機)伺服器,請求讀取數據。 Da ...
目錄
1.5.5 HDFS讀寫解析
1.5.5.1 HDFS讀數據流程
- 客戶端通過Distributed FileSystem向NameNode請求下載文件,NameNode通過查詢元數據, 找到文件塊所在的DataNode地址。
- 挑選一臺DataNode(就近原則,然後隨機)伺服器,請求讀取數據。
- DataNode開始傳輸數據給客戶端(從磁碟裡面讀取數據輸入流,以Packet為單位來做校驗)。
- 客戶端以Packet為單位接收,先在本地緩存,然後寫入目標文件。
1.5.5.2 HDFS寫數據流程
-
客戶端通過Distributed FileSystem模塊向NameNode請求上傳文件,NameNode檢查目標文件是否已存在,父目錄是否存在。
-
NameNode返回是否可以上傳。
-
客戶端請求第一個 Block上傳到哪幾個DataNode伺服器上。
-
NameNode返回3個DataNode節點,分別為dn1、dn2、dn3。
-
客戶端通過FSDataOutputStream模塊請求dn1上傳數據,dn1收到請求會繼續調用dn2,然後dn2調用dn3,將這個通信管道建立完成。
-
dn1、dn2、dn3逐級應答客戶端。
-
客戶端開始往dn1上傳第一個Block(先從磁碟讀取數據放到一個本地記憶體緩存),以Packet為單位,dn1收到一個Packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個確認隊列等待確認。
-
當一個Block傳輸完成之後,客戶端再次請求NameNode上傳第二個Block的伺服器。(重覆執行 3-7步)。
驗證Packet代碼
@Test
public void testUploadPacket() throws IOException {
//1 準備讀取本地文件的輸入流
final FileInputStream in = new FileInputStream(new File("e:/lagou.txt"));
//2 準備好寫出數據到hdfs的輸出流
final FSDataOutputStream out = fs.create(new Path("/lagou.txt"), new Progressable() {
public void progress () { //這個progress方法就是每傳輸64KB(packet)就會執行一次,
System.out.println("&");
}
});
//3 實現流拷貝
IOUtils.copyBytes(in, out, configuration); //預設關閉流選項是true,所以會自動 關閉
//4 關流 可以再次關閉也可以不關了
}