1. 程式人生 > >Hadoop理論——hdfs讀、寫流程

Hadoop理論——hdfs讀、寫流程

在Hadoop中我們一定會使用hdfs的傳輸,那麼,hdfs的讀寫流程究竟是什麼,我利用了一點時間整理了一下
首先就是官網的圖,介紹了HDFS

hdfs寫流程
1,客戶端client呼叫DistributedFileSystem這個物件的create方法去和NameNode這個節點進行rpc通訊,然後NameNode來檢查create這個方法所傳輸過來的hdfs_path這個路徑是否已經存在以及是否有這個許可權在這個路徑裡建立檔案,都沒有問題的話就在這個路徑下建立一個新的空檔案,由於是空檔案因此沒有和任何block關聯,同時返回一個FSDataOutputStream物件給client(這整個過程對於使用者來說是完全透明的,我們並不知道發生了什麼,我們只是使用了hdfs dfs -put file hdfs_path這個命令,而hdfs_path這個路徑就是create裡的那個路徑引數)。如果路徑無效就返回一個錯誤提示或者無許可權建立都會返回錯誤異常。(因此第一步最終要的是從NameNode那裡拿到一個FSDataOutputStream的物件)

2,client呼叫FSDataOutputStream物件的write方法將第一個塊寫給要儲存的第一個DataNode(這裡簡稱DN1),當第一個副本寫入完成後,DN1將資料複製到DN2,當DN2寫入完成後,DN2又將資料複製到DN3,當DN3也寫入完成後,DN3將返回一個ack確認包給DN2,DN2受到DN3的ack確認包後,也返回一個ack確認包給DN1,當DN1受到來自DN2的ack確認包時就意味著DN3和DN2都完成寫入了,這個時候DN1也返回一個ack確認包給FSDataOutputStream物件,這就標誌著第一個資料塊已完成所有副本的寫入過程了。

接下來的資料塊也是按照這個邏輯順序繼續執行下去的,直到最後一個數據塊完成寫入。

3,當整個檔案完成寫入後client呼叫FSDataOutputStream的close方法來關閉輸出流,然後flush掉快取區的資料包。

4,最後client再次呼叫FileSystem物件的complete方法告訴NameNode,檔案完成寫入流程了,同時記錄一個editlog編輯日誌檔案。

這裡我們再總結一下,就是client要寫入的話首先要通過NameNode來確定寫入的路徑沒有檔案同時有許可權寫入新檔案到指定路徑,這樣才能從NameNode那裡獲取到FSDataOutputStream這個輸出流的物件。而client要將檔案的資料塊寫入到DataNode就是要通過FSDataOutputStream物件的write方法來寫入,而完成寫入後client也是通過呼叫FileSystem物件的complete方法來告訴NameNaode寫入完成。

所以我們可以理解為:FileSystem這個物件是client和NameNode進行溝通的物件,而FSDataOutputStream則是client和DataNode進行溝通的物件。
hdfs讀流程
讀流程所涉及到的有client,NameNode和DataNode這個三個,我們來了解下這三個之間在讀流程裡都是幹什麼的。

1,當我們輸入一條讀入資料的命令的時候,如:hdfs dfs -ls / 或者 hdfs dfs -cat /user/hadoop/xxx時,client就通過DistributedFileSystem這個物件的open方法去和NameNode進行rpc通訊,其中open方法會將一個path路徑傳遞過去,這個path路徑就是我們要檢視的檔案或者資料夾的路徑。NameNode會對這個path進行交驗,判斷是否存在這個路徑以及你要讀取的路徑你是否擁有許可權去讀取,如果都沒問題的話就接著第二步,否則報錯。

2,交驗完成後返回一個FSDataInputStream物件,當要讀取前client還要向NameNode傳送一次請求,然後NN將會返回要讀取的檔案的全部或者一部分block列表,這些就是blockmap的內容嘛,還記不記得前幾篇的有介紹到hdfs的寫流程,其中說到DataNode會返回心跳包給NameNode以及每隔10個心跳包就會返回一個blockmap給NameNode,裡面就記錄了每個檔案所對應的block以及其儲存的節點位置。

3,client呼叫FSDataInputStream物件的read方法去讀取每一個block最近地址的副本(雖然有多個副本但是並不是要讀取全部副本的,所以會根據一個演算法來讀取離client最近節點上的副本),讀取完成後回去交驗這個block是否有損壞,假如沒有任何問題會自動關閉與當前DataNode的通訊。如果check失敗了,會記錄下這個受損的block在哪個DataNode節點上,下次不會再讀取了。

4,然後就是下個block的讀取,當我們把block列表裡面的block讀取完後,檔案還沒有結束將繼續向NameNode申請下一批block列表。

5,最後client呼叫FSDataInputStream物件的close方法關閉輸入流。

作者:簡簞
來源:CSDN
原文:https://blog.csdn.net/weixin_43267534/article/details/83901175
版權宣告:本文為博主原創文章,轉載請附上博文連結!