1. 程式人生 > >HDFS讀寫流程(重點)

HDFS讀寫流程(重點)

@[toc] # 寫資料流程 ①服務端啟動HDFS中的`NN和DN`程序 ②客戶端建立一個分散式檔案系統客戶端,由客戶端向NN傳送請求,請求上傳檔案 ③NN處理請求,檢查客戶端是否有許可權上傳,路徑是否合法等 ④檢查通過,NN響應客戶端可以上傳 ⑤客戶端根據自己設定的塊大小,開始上傳`第一個塊`,預設0-128M, NN根據客戶端上傳檔案的副本數(預設為3),根據機架感知策略選取指定數量的DN節點返回 ⑥客戶端根據返回的DN節點,請求`建立傳輸通道` 客戶端向最近(網路距離最近)的DN節點發起通道建立請求,由這個DN節點依次向通道中的(距離當前DN距離最近) 下一個節點發送建立通道請求,各個節點發送響應 ,通道建立成功 ⑦客戶端每讀取`64K`的資料,封裝為一個`packet`(資料包,傳輸的基本單位),將packet傳送到通道的下一個節點 通道中的節點收到packet之後,落盤(檢驗)儲存,將packet傳送到通道的下一個節點! 每個節點在收到packet後,向客戶端傳送`ack`確認訊息! ⑧一個塊的資料傳輸完成之後,通道關閉,DN向NN上報訊息,已經收到某個塊 ⑨第一個塊傳輸完成,第二塊開始傳輸,依次重複⑤-⑧,直到最後一個塊傳輸完成,NN向客戶端響應傳輸完成! ⑩客戶端關閉輸出流 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200708203550760.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RURlRf,size_16,color_FFFFFF,t_70) ## 舉例: 1)客戶端通過Distributed FileSystem模組向NameNode請求上傳檔案,NameNode檢查目標檔案是否已存在,父目錄是否存在。 2)NameNode返回是否可以上傳。 3)客戶端請求第一個 Block上傳到哪幾個DataNode伺服器上。 4)NameNode返回3個DataNode節點,分別為dn1、dn2、dn3。 5)客戶端通過FSDataOutputStream模組請求dn1上傳資料,dn1收到請求會繼續呼叫dn2,然後dn2呼叫dn3,將這個通訊管道建立完成。 6)dn1、dn2、dn3逐級應答客戶端。 7)客戶端開始往dn1上傳第一個Block(先從磁碟讀取資料放到一個本地記憶體快取),以Packet為單位,dn1收到一個Packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個應答佇列等待應答。 8)當一個Block傳輸完成之後,客戶端再次請求NameNode上傳第二個Block的伺服器。(重複執行3-7步)。 @[toc] # 異常寫流程 ①-⑥見上 ⑦客戶端每讀取64K的資料,封裝為一個packet,封裝成功的packet,放入到一個佇列中,這個佇列稱為`dataQuene`(待發送資料包) 在傳送時,先將dataQuene中的packet按順序傳送,傳送後再放入到`ackquene`(正在傳送的佇列)。 每個節點在收到packet後,向客戶端傳送ack確認訊息! 如果一個packet在傳送後,已經收到了所有DN返回的ack確認訊息,這個packet會在ackquene中刪除! 假如一個packet在傳送後,在收到DN返回的ack確認訊息時超時,傳輸中止,ackquene中的packet會回滾到dataQuene。 重新建立通道,剔除壞的DN節點。建立完成之後,繼續傳輸! 只要有一個DN節點收到了資料,DN上報NN已經收完此塊,NN就認為當前塊已經傳輸成功! NN會自動維護副本數! @[toc] # 讀資料流程 1)客戶端通過`Distributed FileSystem`向`NameNode`請求下載檔案,NameNode通過查詢元資料,找到檔案塊所在的DataNode地址。 2)挑選一臺DataNode(就近原則,然後隨機)伺服器,請求讀取資料。 3)DataNode開始傳輸資料給客戶端(從磁盤裡面讀取資料輸入流,以Packet為單位來做校驗)。 4)客戶端以Packet為單位接收,先在本地快取,然後寫入目標文