
HDFS讀數據流程簡述
- 客戶端向NameNode發起讀數據請求;
- NameNode響應請求並告訴客戶端要讀的文件的數據塊位置(存在哪個DataNode上);
- 客戶端到對應DataNode讀取數據,當數據讀取到達末端,關閉與這個DataNode的連接,並查找下一個數據塊,直到文件數據全部讀完;
- 最后關閉輸出流。
- 客戶端調用FileSystem 實例的open 方法,獲得這個文件對應的輸入流InputStream。
- 通過RPC 遠程調用NameNode ,獲得NameNode 中此文件對應的數據塊保存位置,包括這個文件的副本的保存位置( 主要是各DataNode的地址) 。
- 獲得輸入流之后,客戶端調用read 方法讀取數據。選擇最近的DataNode 建立連接並讀取數據。
- 如果客戶端和其中一個DataNode 位於同一機器(比如MapReduce 過程中的mapper 和reducer),那么就會直接從本地讀取數據。
- 到達數據塊末端,關閉與這個DataNode 的連接,然后重新查找下一個數據塊。
- 不斷執行第2 - 5 步直到數據全部讀完。
- 客戶端調用close ,關閉輸入流DFS InputStream
HDFS寫入數據簡述:
- 客戶端向NameNode發起寫數據請求;
- NameNode相應請求(NameNode會檢查要創建的文件是否已經存在,創建者是否有權限,成功會創建一個記錄,失敗會報異常);
- 客戶端將文件進行切片(分成數據塊),然后上傳數據塊,按照一個一個的形式進行發送,每個數據塊都要寫到三個DataNode上;
- 成功后DataNode會返回一個確認隊列給客戶端,客戶端進行效驗,然后客戶端上傳下一個數據塊到DataNode,直到所有數據塊寫入完成;
- 當所有數據塊全部寫入成功后,客戶端會向NameNode發送一個反饋並關閉數據流。
詳細說明:
1、使用 HDFS 提供的客戶端 Client,向遠程的 namenode 發起 RPC 請求;
2、namenode 會檢查要創建的文件是否已經存在,創建者是否有權限進行操作,成功則會 為文件創建一個記錄,否則會讓客戶端拋出異常;
3、當客戶端開始寫入文件的時候,客戶端會將文件切分成多個 packets,並在內部以數據隊列“data queue(數據隊列)”的形式管理這些 packets,並向 namenode 申請 blocks,獲 取用來存儲 replicas 的合適的 datanode 列表,列表的大小根據 namenode 中 replication 的設定而定;
4、開始以 pipeline(管道)的形式將 packet 寫入所有的 replicas 中。客戶端把 packet 以流的 方式寫入第一個 datanode,該 datanode 把該 packet 存儲之后,再將其傳遞給在此 pipeline 中的下一個 datanode,直到最后一個 datanode,這種寫數據的方式呈流水線的形式;
5、最后一個 datanode 成功存儲之后會返回一個 ack packet(確認隊列),在 pipeline 里傳遞 至客戶端,在客戶端的開發庫內部維護着"ack queue",成功收到 datanode 返回的 ack packet 后會從"data queue"移除相應的 packet;
6、如果傳輸過程中,有某個 datanode 出現了故障,那么當前的 pipeline 會被關閉,出現故 障的 datanode 會從當前的 pipeline 中移除,剩余的 block 會繼續剩下的 datanode 中繼續 以 pipeline 的形式傳輸,同時 namenode 會分配一個新的 datanode,保持 replicas 設定的 數量;
7、客戶端完成數據的寫入后,會對數據流調用 close()方法,關閉數據流。
