HDFS的文件讀取與寫入流程

文件讀取流程node

    1)  客戶端首先要調用FileSystem對象的靜態方法open()方法來打開一個但願讀取文件的路徑,在HDFS中文件的對象爲Path對象(與Java中的File相對應)。異步

    2) FileSystem對象就是一個DistributedFileSystem對象,經過利用RPC來調用NameNode節點,(NameNode節點存儲着整個文件系統目錄、文件以及文件所在塊的位置信息),來肯定咱們須要打開的文件全部數據塊的存儲位置。文件在被存入HDFS中,會被劃分爲多個數據塊存儲的,對於每個數據塊,namenode都會返回存有該數據塊副本的datanode地址。數據塊副本的datanode地址會根據與客戶端的距離來排序。DistributedFileSystem返回一個FSDataInputStream對象給client用來讀取數據。FSDataInputStream封裝了DFSInputStream對象,該對象用於管理NameNodeDataNodeI/Oide

   3) 客戶端利用該FSDataInputStream對象的輸入流調用read()方法。輸入流會首先讀取距離客戶端最近的datanode,反覆讀取,直到將該datanode數據讀取完後,而後就會FSDataInputStream關閉與該datanode的鏈接,而後繼續尋找下一個datanode節點。oop

  4) 客戶端讀取文件,數據塊都是按照DFSInputStream與datanode鏈接的距離順序讀取,也會詢問namenode下一批數據塊的datanode位置,整個文件讀取完後,就會立刻調用FSDataInputStream的close()方法。spa

       讀取中的失敗錯誤處理:當讀取數據時,DFSInputStream與datanode通訊失敗,則會讀取這個塊的最接近該datanode的節點來讀取數據,而且之後不會反覆讀取該失敗節點。3d

      namenode僅僅提供給客戶端檢索文件的做用,告知客戶端每一個塊最佳datanode(利用排序),它僅僅響應數據塊位置的請求,而無需響應數據請求。具體的數據流都是由客戶端與datanode直接通訊的。對象


文件寫入流程blog

   

1). client經過調用DistributedFileSystemcreate()方法來建立文件。排序

2). DistributedFileSystem經過RPC調用NameNode在文件系統的名字空間裏建立一個新文件,名稱節點首先肯定文件原來不存在,而且客戶端有建立文件的權限,而後建立新文件,這個時候尚未任何塊的信息。DistributedFileSystem返回FSDataOutputStreamclientFSDataOutputStream封裝了一個DFSOutputStream對象,該對象負責處理datanodenamenode之間的通信。隊列

3). 當Client開始寫數據的時候,DFSOutputStream把文件的數據分紅一個個數據包,並寫入內部對列DataQueueDataQueue是由DataStreamer負責讀取,DataStreamer通知NameNode分配DataNode,用來存儲數據塊(每塊默認複製3),分配的DataNode列表造成一個管道(pipeline)。在上圖中管道由三個datanode組成,這三個datanode的選擇有必定的副本放置策略。

4).  DataStreamer將數據塊流式傳輸到pipeline中的第一個DataNode,第一個DataNode存儲數據塊並將數據塊發送給pipeline中的第二個DataNode,一樣的,第二個DataNode存儲數據塊並將數據塊發送給pipeline中的第三個DataNode

5). 同時,DFSOutputStream也管理ackqueue(確認隊列),ackqueue裏存儲着等待datanode識別的數據塊,只有當管道里全部datanode都返回寫入成功,這個數據塊纔算寫成功,纔會從ackqueue中刪除,開始寫下一個數據塊。

      若是某個datanode發生故障,寫失敗了,則會執行以下步驟,可是這些對client是透明的。

     1) 管道關閉。

     2)正常的datanode上的當前block會有一個新ID,並將該ID傳送給namenode,以便失敗的datanode在恢復後能夠刪除那個不完整的block

    3) 失敗的datanode會被移出管道,餘下的數據塊繼續寫入管道的其餘兩個正常的datanode

    4) namenode會標記這個block的副本個數少於指定值。block的副本會稍後在另外一個datanode建立。

     5)有些時候多個datanode會失敗,但很是少見。只要dfs.replication.min(缺省是1)datanode成功了,整個寫入過程就算成功。缺乏的副本會在集羣中異步的複製,直到達到正常的副本數。

6. client完成了全部block的寫入後,調用FSDataOutputStreamclose()方法關閉文件。

7. FSDataOutputStream通知namenode寫文件結束。
    文件寫入中的副本策略:

1) Hadoop默認副本策略是將第一個複本放在運行客戶端的節點上,即上傳文件或者寫入文件所在的datanode節點上。若是客戶端不在集羣中,則就隨機選擇一個節點。

2) 第二個複本放在與第一個複本不一樣且隨機的另外的機架上。

3) 第三個複本與第二個複本放在相同的機架上。

相關文章
相關標籤/搜索