閱讀327 返回首頁    go 阿裏雲 go 技術社區[雲棲]


基於Hadoop雲盤係統1:上傳和下載效率優化

 一、讀寫機製

首先來看文件讀取機製:盡管DataNode實現了文件存儲空間的水平擴展和多副本機製,但是針對單個具體文件的讀取,Hadoop默認的API接口並沒有提供多DataNode的並行讀取機製。基於Hadoop提供的API接口實現的雲盤客戶端也自然麵臨同樣的問題。Hadoop的文件讀取流程如下圖所示:

  1. 使用HDFS提供的客戶端開發庫,向遠程的Namenode發起RPC請求;
  2. Namenode會視情況返回文件的部分或者全部block列表,對於每個block,Namenode都會返回有該block拷貝的datanode地址;
  3. 客戶端開發庫會選取離客戶端最接近的datanode來讀取block;
  4. 讀取完當前block的數據後,關閉與當前的datanode連接,並為讀取下一個block尋找最佳的datanode;
  5. 當讀完列表的block後,且文件讀取還沒有結束,客戶端開發庫會繼續向Namenode獲取下一批的block列表。
  6. 讀取完一個block都會進行checksum驗證,如果讀取datanode時出現錯誤,客戶端會通知Namenode,然後再從下一個擁有該block拷貝的datanode繼續讀取。

這裏需要注意的關鍵點是:多個Datanode順序讀取。

其次再看文件的寫入機製:

  1. 使用HDFS提供的客戶端開發庫,向遠程的Namenode發起RPC請求;
  2. Namenode會檢查要創建的文件是否已經存在,創建者是否有權限進行操作,成功則會為文件創建一個記錄,否則會讓客戶端拋出異常;
  3. 當客戶端開始寫入文件的時候,開發庫會將文件切分成多個packets,並在內部以"data queue"的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表, 列表的大小根據在Namenode中對replication的設置而定。
  4. 開始以pipeline(管道)的形式將packet寫入所有的replicas中。開發庫把packet以流的方式寫入第一個 datanode,該datanode把該packet存儲之後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個 datanode,這種寫數據的方式呈流水線的形式。
  5. 最後一個datanode成功存儲之後會返回一個ack packet,在pipeline裏傳遞至客戶端,在客戶端的開發庫內部維護著"ack queue",成功收到datanode返回的ack packet後會從"ack queue"移除相應的packet。
  6. 如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的 pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的 datanode,保持replicas設定的數量。

關鍵詞:開發庫把packet以流的方式寫入第一個datanode,該datanode將其傳遞給pipeline中的下一個datanode,知道最後一個Datanode,這種寫數據的方式呈流水線方式。

二、解決方案

1.下載效率優化

通過以上讀寫機製的分析,我們可以發現基於Hadoop實現的雲盤客戶段下載效率的優化可以從兩個層級著手:

1.文件整體層麵:采用並行訪問多線程(多進程)份多文件並行讀取。

2.Block塊讀取:改寫Hadoop接口擴展,多Block並行讀取。

2.上傳效率優化

上傳效率優化隻能采用文件整體層麵的並行處理,不支持分Block機製的多Block並行讀取。

最後更新:2017-04-03 22:15:39

  上一篇:go Android分別使用HTTP協議和TCP協議實現上傳文件
  下一篇:go 華為員工加盟IBM後的詫異