HDFS 基本原理

隨着互聯網的發展,數據日益增多,增長超過了單機能夠處理的上線,數據如何存儲和處理成爲了科技公司的難題,隨着google的三篇論文的發佈,大家終於找到了一個方案-分佈式文件系統+MapReduce。Hadoop是參考google論文實現的,集成了分佈式文件系統與分佈式批處理平臺。hadoop的設計目標是用來解決大文件海量存儲和批處理的,爲了避免單個節點故障導致數據丟失,設計副本冗餘機制。 本文將主要分析一下幾個方面:

  • HDFS的概念與架構

  • 讀寫流程分析

  • 使用場景與缺點

HDFS的概念與架構

HDFS採用的master/slave架構。一個HDFS集羣通常由一個Active的NameNode和若干DataNode組成,爲了避免NameNode單點問題,通常會做一個NameNode的standby作爲備份。在整個hdfs涉及到許多的核心概念,下面做一個簡單介紹:

  • NameNode: NameNode是一箇中心服務器,負責管理文件系統的名字空間以及客戶端的訪問,比如文件的打卡、關閉、重命名文件或者目錄。它負責確定數據塊到具體的存儲節點的映射。在其同意調度下進行數據塊的創建、刪除、複製。

  • DataNode: DataNode是HDFS的實際存儲節點,負責管理它所在節點的存儲;客戶端的讀寫請求。並且定期上報心跳和塊的存儲位置。

  • Block: HDFS上文件,從其內部看,一個文件其實是被分成一個或者多個數據塊存儲的,這些數據塊存儲在一組DataNode上。

  • Edits: 在HDFS發起的創建、刪除等操作其實是一個事物,事物在NameNode上以Edit對象存儲在edits文件中,持久化在NameNode的本地磁盤上。

  • FSimage: FSimage是NameNode的元數據存儲快照,持久化在NameNode的本地磁盤上。

當NameNode重啓的時候,NameNode從FSImage和Edits文件中讀取數據,加載到內存中。

在HDFS體系來看,NameNode主要負責元數據的存儲與操作,DataNode負責實際的存儲。DataNode通常在一個機器上部署一個進程,這些機器分佈式在多個機架上。整體架構如下圖所示:

HDFS的讀寫流程

讀流程分析

  • 客戶端打開文件,通過rpc的方式向NameNode獲取文件塊的存儲位置信息,NameNode會將文件中的各個塊的所有副本DataNode全部返回,這些DataNode會按照與客戶端的位置的距離排序。如果客戶端就是在DataNode上,客戶端可以直接從本地讀取文件,跳過網絡IO,性能更高。
  • 客戶端調用read方法,存儲了文件的前幾個塊的地址的DFSInputStream,就會連接存儲了第一個塊的最近的DataNode。然後通過DFSInputStream就通過重複調用read()方法,數據就從DataNode流動到客戶端,當DataNode的最後一個塊讀取完成了,DFSInputSteam會關閉與DataNode的連接,然後尋找下一個快的最佳節點。這個過程讀客戶端來說透明的,在客戶端那邊來看們就像是隻讀取了一個連續不斷的流。
  • 塊是按順序讀的,通過 DFSInputStream 在 datanode 上打開新的連接去作爲客戶端讀取的流。他也將會通過namenode 來獲取下一批所需要的塊所在的 datanode 的位置(注意剛纔說的只是從 namenode 獲取前幾個塊的)。當客戶端完成了讀取,就在 FSDataInputStream 上調用 close() 方法結束整個流程。

在這個設計中一個重要的方面就是客戶端直接從 DataNode 上檢索數據,並通過 NameNode 指導來得到每一個塊的最佳 DataNode。這種設計允許 HDFS 擴展大量的併發客戶端,因爲數據傳輸只是集羣上的所有 DataNode 展開的。期間,NameNode 僅僅只需要服務於獲取塊位置的請求(塊位置信息是存放在內存中,所以效率很高)。如果不這樣設計,隨着客戶端數據量的增長,數據服務就會很快成爲一個瓶頸。

寫流程分析

  • 通過Client向遠程的NameNode發送RPC請求;

  • 接收到請求後NameNode會首先判斷對應的文件是否存在以及用戶是否有對應的權限,成功則會爲文件創建一個記錄,否則會讓客戶端拋出異常;

  • 當客戶端開始寫入文件的時候,開發庫會將文件切分成多個packets,並在內部以"data queue"的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表,列表的大小根據在Namenode中對replication的設置而定。

  • 開始以pipeline(管道)的形式將packet寫入所有的replicas中。開發庫把packet以流的方式寫入第一個 datanode,該datanode把該packet存儲之後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個 datanode, 這種寫數據的方式呈流水線的形式。

  • 最後一個datanode成功存儲之後會返回一個ack packet,在pipeline裏傳遞至客戶端,在客戶端的開發庫內部維護着 "ack queue",成功收到datanode返回的ack packet後會從"ack queue"移除相應的packet。

  • 如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的 pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的 datanode,保持replicas設定的數量。

HDFS的使用場景和缺點

使用場景

  • hdfs的設計一次寫入,多次讀取,支持修改。

  • 大文件,在hdfs中一個塊通常是64M、128M、256M,小文件會佔用更多的元數據存儲,增加文件數據塊的尋址時間。

  • 延時高,批處理。

  • 高容錯,多副本。

缺點

  • 延遲比較高,不適合低延遲高吞吐率的場景

  • 不適合小文件,小文件會佔用NameNode的大量元數據存儲內存,並且增加尋址時間

  • 支持併發寫入,一個文件只能有一個寫入者

  • 不支持隨機修改,僅支持append

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章