hadoop入門(12):hdfs的讀寫流程
阿新 • • 發佈:2022-03-08
hdfs的寫入流程
檔案具體上傳流程如下:
-
建立檔案:
- HDFS client向HDFS寫資料先呼叫DistributedFileSystem.create()
- RPC呼叫namenode的create()方法,會在HDFS目錄樹中指定路徑,新增新檔案;並將操作記錄在edits.log中。namenode的create()方法執行完後,返回一個FSDataOutPutStream,他是DFSOutPutStream的包裝類
-
建立資料流管道pipeline
- client呼叫DFSOutPutStream.write()寫資料(先寫檔案的第一個塊,暫時稱為blk1)
- DFSOutputStream通過RPC呼叫namenode的addBlock,向namenode申請一個空的資料塊block
- addBlock返回一個LocatedBlock物件,此物件包含當前blk要儲存哪三個datanode資訊,比如dn1,dn2,dn3
- 客戶端根據位置資訊建立資料流管道
-
向資料流管道寫入當前塊的資料
- 寫資料時,先將資料寫入一個檢驗塊chunk中,寫滿512位元組後,對此chunk計算校驗和chunksum值(4位元組)
- 然後將chunk和對應的校驗寫入packet中,一個packet是64kb
- 隨著源源不斷的帶校驗chunk寫入packet,當packet寫滿之後將其寫入dataqueue佇列中
- packet從佇列中取出,沿著pipeline傳送到dn1,再從dn1傳送到dn2,dn2傳送到dn3
- 同時,這個packet也會儲存一份到一個確認佇列ack queue中
- packet到達最後一個datanode即nd3之後會做檢驗,然後將檢驗沿結果逆著pipeline方向傳回客戶端,具體檢驗結果從dn3傳到dn2,dn2做檢驗,dn2傳到dn1,dn1做檢驗,結果再傳回客戶端。
- 客戶端根據校驗結果,如果“成功”,則將儲存在ack queue中的packet刪除,如果失敗則將packet取出重新放回到dataqueue末尾,等待沿pipeline再次傳輸。
- 如此將block中一個數據的一個個packet傳送出去。當block傳送完畢,即dn1,dn2,dn3都接收了blk1的副本,那麼三個datanode分別RPC呼叫namenode的blockReceivedAndDeleted(),namenode會更新記憶體中block與datanode的對應關係(比如dn1上多了個blk1)
-
關閉三個datanode構建的pipeline,且檔案還有下一個塊的時候,再從4開始直到全部檔案寫完
- 最終,呼叫DFSOutputStream的close()。
- 客戶端呼叫namenode的complete(),告知namenode檔案傳輸完成。
HDFS寫資料-容錯
Q: 如果在傳輸過程中dn2掛了,則當前piprline中斷,hdfs會怎麼樣?
A: 客戶端RPC會呼叫namenode的updateBlockPipeline()為當前block(假設為blk1)生成新的版本比如ts1(本質上是時間戳),故障dn2會從pipeline中刪除。
DFSOutputStream再RPC呼叫namenode的getAdditionalDatanode()讓namenode重新分配datanode假設為dn4。讓dn1、dn3、dn4組成新的管道,他們上邊的blk1版本設定為新版本ts1.
由於dn4上沒有blk1的資料,客戶端告訴dn1、dn3將其上的blk1資料拷貝給dn4.
新的管道建立好之後,DFSOutputStream呼叫updatePipeline()更新namenode元資料。到此,pipeline恢復,客戶端繼續上傳檔案。
故障的datanode重啟後,namenode發現其上面的blk1的時間戳是老的,會讓datanode將blk1刪除掉。
hdfs的讀取流程
檔案的具體讀取流程如下:
- Client端讀取hdfs檔案,client呼叫檔案系統物件DistributedFileSystem的open方法
- 返回FSDataInputStream物件(對DFSInputStream的包裝)
- 構造DFSInputStream物件時,呼叫namenode的getBlockLocation方法,獲得file開始的若干個block的儲存datanode列表;針對每個block的dn列表,會根據網路拓撲排序,離client近的排在前面。
- 呼叫DFSInputStream的read方法讀取blk1的資料,與client最近的datanode建立連線,讀取資料。
- 讀取完後,關閉與dn建立的流。
- 重複4、5、6步驟,緊接著讀取下一個塊的資料,直到這一批塊的資料讀完。
- 讀取下一批塊,重複3、4、5、6、7
- 呼叫FSDataInputStream的close方法
HDFS讀資料-容錯
Q: 讀取block資料時,client與datanode連線中斷會怎麼辦?
A: client與第二個儲存此block的datanode建立連線,儲存資料。記錄出問題的datanode,不會再從其上讀取資料。
Q: client讀取資料時,發現block塊的資料有問題怎麼辦?
A: client讀取資料時,同時會讀取到block的校驗和,若client針對讀取的block計算校驗和發現與其讀取的校驗和不一致,說明block損壞。client會從其它存放此block的datanode讀取資料,同樣會計算校驗和,同時告訴namenode此情況。