Hadoop分佈式文件系統:架構和設計要點

Hadoop分佈式文件系統:架構和設計要點
原文:http://hadoop.apache.org/core/docs/current/hdfs_design.html
一、前提和設計目標
1、硬件錯誤是常態,而非異常情況, HDFS可能是有成百上千的 server組成,任何一個組件都有可能一直失效,因此錯誤檢測和快速、自動的恢復是 HDFS的核心架構目標。
2、跑在 HDFS上的應用與一般的應用不同,它們主要是以流式讀爲主,做批量處理;比之關注數據訪問的低延遲問題,更關鍵的在於數據訪問的高吞吐量。
3 HDFS以支持大數據集合爲目標,一個存儲在上面的典型文件大小一般都在千兆至 T字節,一個單一 HDFS實例應該能支撐數以千萬計的文件。
4 HDFS應用對文件要求的是 write-one-read-many訪問模型。一個文件經過創建、寫,關閉之後就不需要改變。這一假設簡化了數據一致性問 題,使高吞吐量的數據訪問成爲可能。典型的如 MapReduce框架,或者一個 web crawler應用都很適合這個模型。
5、移動計算的代價比之移動數據的代價低。一個應用請求的計算,離它操作的數據越近就越高效,這在數據達到海量級別的時候更是如此。將計算移動到數據附近,比之將數據移動到應用所在顯然更好, HDFS提供給應用這樣的接口。
6、在異構的軟硬件平臺間的可移植性。

二、 Namenode Datanode
    HDFS採用 master/slave架構。一個 HDFS集羣是有一個 Namenode和一定數目的 Datanode組成。 Namenode是一箇中心服 務器,負責管理文件系統的 namespace和客戶端對文件的訪問。 Datanode在集羣中一般是一個節點一個,負責管理節點上它們附帶的存儲。在內 部,一個文件其實分成一個或多個 block,這些 block存儲在 Datanode集合裏。 Namenode執行文件系統的 namespace操作,例如 打開、關閉、重命名文件和目錄,同時決定 block到具體 Datanode節點的映射。 Datanode Namenode的指揮下進行 block的創 建、刪除和複製。 Namenode Datanode都是設計成可以跑在普通的廉價的運行 linux的機器上。 HDFS採用 java語言開發,因此可以部 署在很大範圍的機器上。一個典型的部署場景是一臺機器跑一個單獨的 Namenode節點,集羣中的其他機器各跑一個 Datanode實例。這個架構並不排 除一臺機器上跑多個 Datanode,不過這比較少見。

單一節點的 Namenode大大簡化了系統的架構。 Namenode負責保管和管理所有的 HDFS元數據,因而用戶數據就不需要通過 Namenode(也就是說文件數據的讀寫是直接在 Datanode上)。

三、文件系統的 namespace
   HDFS支持傳統的層次型文件組織,與大多數其他文件系統類似,用戶可以創建目錄,並在其間創建、刪除、移動和重命名文件。 HDFS不支持 user quotas和訪問權限,也不支持鏈接( link),不過當前的架構並不排除實現這些特性。 Namenode維護文件系統的 namespace,任何對文 件系統 namespace和文件屬性的修改都將被 Namenode記錄下來。應用可以設置 HDFS保存的文件的副本數目,文件副本的數目稱爲文件的 replication因子,這個信息也是由 Namenode保存。

四、數據複製
    HDFS被設計成在一個大集羣中可以跨機器地可靠地存儲海量的文件。它將每個文件存儲成 block序列,除了最後一個 block,所有的 block都是同 樣的大小。文件的所有 block爲了容錯都會被複制。每個文件的 block大小和 replication因子都是可配置的。 Replication因子可 以在文件創建的時候配置,以後也可以改變。 HDFS中的文件是 write-one,並且嚴格要求在任何時候只有一個 writer Namenode全權管 理 block的複製,它週期性地從集羣中的每個 Datanode接收心跳包和一個 Blockreport。心跳包的接收表示該 Datanode節點正常工 作,而 Blockreport包括了該 Datanode上所有的 block組成的列表。


1、副本的存放,副本的存放是 HDFS可靠性和性能的關鍵。 HDFS採用一種稱爲 rack-aware的策略來改進數據的可靠性、有效性和網絡帶寬的利 用。這個策略實現的短期目標是驗證在生產環境下的表現,觀察它的行爲,構建測試和研究的基礎,以便實現更先進的策略。龐大的 HDFS實例一般運行在多個機 架的計算機形成的集羣上,不同機架間的兩臺機器的通訊需要通過交換機,顯然通常情況下,同一個機架內的兩個節點間的帶寬會比不同機架間的兩臺機器的帶寬 大。
    通過一個稱爲 Rack Awareness的過程, Namenode決定了每個 Datanode所屬的 rack id。一個簡單但沒有優化的策略就是將副本存放在單獨的機架上。這樣可以防止整個機架(非副本存放)失效的情況,並且允許讀數據的時候可以從多個機架讀 取。這個簡單策略設置可以將副本分佈在集羣中,有利於組件失敗情況下的負載均衡。但是,這個簡單策略加大了寫的代價,因爲一個寫操作需要傳輸 block到 多個機架。
    在大多數情況下, replication因子是 3 HDFS的存放策略是將一個副本存放在本地機架上的節點,一個副本放在同一機架上的另一個節點,最後一 個副本放在不同機架上的一個節點。機架的錯誤遠遠比節點的錯誤少,這個策略不會影響到數據的可靠性和有效性。三分之一的副本在一個節點上,三分之二在一個 機架上,其他保存在剩下的機架中,這一策略改進了寫的性能。

2、副本的選擇,爲了降低整體的帶寬消耗和讀延時, HDFS會盡量讓 reader讀最近的副本。如果在 reader的同一個機架上有一個副本,那麼就讀該副本。如果一個 HDFS集羣跨越多個數據中心,那麼 reader也將首先嚐試讀本地數據中心的副本。

3 SafeMode
    Namenode啓動後會進入一個稱爲 SafeMode的特殊狀態,處在這個狀態的 Namenode是不會進行數據塊的複製的。 Namenode從所有的 Datanode接收心跳包和 Blockreport Blockreport包括了某個 Datanode所有的數據塊列表。每個 block都有指定的最 小數目的副本。當 Namenode檢測確認某個 Datanode的數據塊副本的最小數目,那麼該 Datanode就會被認爲是安全的;如果一定百分比(這 個參數可配置)的數據塊檢測確認是安全的,那麼 Namenode將退出 SafeMode狀態,接下來它會確定還有哪些數據塊的副本沒有達到指定數目,並將 這些 block複製到其他 Datanode

五、文件系統元數據的持久化
    Namenode存儲 HDFS的元數據。對於任何對文件元數據產生修改的操作, Namenode都使用一個稱爲 Editlog的事務日誌記錄下來。例如, 在 HDFS中創建一個文件, Namenode就會在 Editlog中插入一條記錄來表示;同樣,修改文件的 replication因子也將往 Editlog插入一條記錄。 Namenode在本地 OS的文件系統中存儲這個 Editlog。整個文件系統的 namespace,包括 block到文件 的映射、文件的屬性,都存儲在稱爲 FsImage的文件中,這個文件也是放在 Namenode所在系統的文件系統上。
    Namenode在內存中保存着整個文件系統 namespace和文件 Blockmap的映像。這個關鍵的元數據設計得很緊湊,因而一個帶有 4G內存的 Namenode足夠支撐海量的文件和目錄。當 Namenode啓動時,它從硬盤中讀取 Editlog FsImage,將所有 Editlog中的事務作 用( apply)在內存中的 FsImage ,並將這個新版本的 FsImage從內存中 flush到硬盤上 ,然後再 truncate這個舊的 Editlog,因爲這個舊的 Editlog的事務都已經 作用在 FsImage上了。這個過程稱爲 checkpoint。在當前實現中, checkpoint只發生在 Namenode啓動時,在不久的將來我們將 實現支持週期性的 checkpoint
    Datanode並不知道關於文件的任何東西,除了將文件中的數據保存在本地的文件系統上。它把每個 HDFS數據塊存儲在本地文件系統上隔離的文件中。 Datanode並不在同一個目錄創建所有的文件,相反,它用啓發式地方法來確定每個目錄的最佳文件數目,並且在適當的時候創建子目錄。在同一個目錄創建 所有的文件不是最優的選擇,因爲本地文件系統可能無法高效地在單一目錄中支持大量的文件。當一個 Datanode啓動時,它掃描本地文件系統,對這些本地 文件產生相應的一個所有 HDFS數據塊的列表,然後發送報告到 Namenode,這個報告就是 Blockreport

六、通訊協議
    所有的 HDFS通訊協議都是構建在 TCP/IP協議上。客戶端通過一個可配置的端口連接到 Namenode,通過 ClientProtocol Namenode交互。而 Datanode是使用 DatanodeProtocol Namenode交互。從 ClientProtocol Datanodeprotocol抽象出一個遠程調用 (RPC),在設計上, Namenode不會主動發起 RPC,而是是響應來自客戶端和 Datanode RPC請求。

七、健壯性
    HDFS的主要目標就是實現在失敗情況下的數據存儲可靠性。常見的三種失敗: Namenode failures, Datanode failures和網絡分割( network partitions)
1、硬盤數據錯誤、心跳檢測和重新複製
    每個 Datanode節點都向 Namenode週期性地發送心跳包。網絡切割可能導致一部分 Datanode Namenode失去聯繫。 Namenode通過心跳包的缺失檢測到這一情況,並將這些 Datanode標記爲 dead,不會將新的 IO請求發給它們。寄存在 dead Datanode上的任何數據將不再有效。 Datanode的死亡可能引起一些 block的副本數目低於指定值, Namenode不斷地跟蹤需要複製的 block,在任何需要的情況下啓動複製。在下列情況可能需要重新複製:某個 Datanode節點失效,某個副本遭到損壞, Datanode上的硬盤錯 誤,或者文件的 replication因子增大。

2、集羣均衡
   HDFS支持數據的均衡計劃,如果某個 Datanode節點上的空閒空間低於特定的臨界點,那麼就會啓動一個計劃自動地將數據從一個 Datanode搬移 到空閒的 Datanode。當對某個文件的請求突然增加,那麼也可能啓動一個計劃創建該文件新的副本,並分佈到集羣中以滿足應用的要求。這些均衡計劃目前 還沒有實現。

3、數據完整性
  從某個 Datanode獲取的數據塊有可能是損壞的,這個損壞可能是由於 Datanode的存儲設備錯誤、網絡錯誤或者軟件 bug造成的。 HDFS客戶端 軟件實現了 HDFS文件內容的校驗和。當某個客戶端創建一個新的 HDFS文件,會計算這個文件每個 block的校驗和,並作爲一個單獨的隱藏文件保存這些 校驗和在同一個 HDFS namespace下。當客戶端檢索文件內容,它會確認從 Datanode獲取的數據跟相應的校驗和文件中的校驗和是否匹配,如果不匹配,客戶端可以選擇 從其他 Datanode獲取該 block的副本。

4、元數據磁盤錯誤
    FsImage Editlog HDFS的核心數據結構。這些文件如果損壞了,整個 HDFS實例都將失效。因而, Namenode可以配置成支持維護多 個 FsImage Editlog的拷貝。任何對 FsImage或者 Editlog的修改,都將同步到它們的副本上。這個同步操作可能會降低 Namenode每秒能支持處理的 namespace事務。這個代價是可以接受的,因爲 HDFS是數據密集的,而非元數據密集。當 Namenode重啓的 時候,它總是選取最近的一致的 FsImage Editlog使用。
   Namenode HDFS是單點存在,如果 Namenode所在的機器錯誤,手工的干預是必須的。目前,在另一臺機器上重啓因故障而停止服務的 Namenode這個功能還沒實現。

5、快照
   快照支持某個時間的數據拷貝,當 HDFS數據損壞的時候,可以恢復到過去一個已知正確的時間點。 HDFS目前還不支持快照功能。

八、數據組織
1、數據塊
    兼容 HDFS的應用都是處理大數據集合的。這些應用都是寫數據一次,讀卻是一次到多次,並且讀的速度要滿足流式讀。 HDFS支持文件的 write- once-read-many語義。一個典型的 block大小是 64MB,因而,文件總是按照 64M切分成 chunk,每個 chunk存儲於不同的 Datanode
2、步驟
    某個客戶端創建文件的請求其實並沒有立即發給 Namenode,事實上, HDFS客戶端會將文件數據緩存到本地的一個臨時文件。應用的寫被透明地重定向到 這個臨時文件。當這個臨時文件累積的數據超過一個 block的大小(默認 64M),客戶端纔會聯繫 Namenode Namenode將文件名插入文件系 統的層次結構中,並且分配一個數據塊給它,然後返回 Datanode的標識符和目標數據塊給客戶端。客戶端將本地臨時文件 flush到指定的 Datanode上。當文件關閉時,在臨時文件中剩餘的沒有 flush的數據也會傳輸到指定的 Datanode,然後客戶端告訴 Namenode文件已經 關閉。此時 Namenode纔將文件創建操作提交到持久存儲。如果 Namenode在文件關閉前掛了,該文件將丟失。
   上述方法是對通過對 HDFS上運行的目標應用認真考慮的結果。如果不採用客戶端緩存,由於網絡速度和網絡堵塞會對吞估量造成比較大的影響。

3、流水線複製
    當某個客戶端向 HDFS文件寫數據的時候,一開始是寫入本地臨時文件,假設該文件的 replication因子設置爲 3,那麼客戶端會從 Namenode 獲取一張 Datanode列表來存放副本。然後客戶端開始向第一個 Datanode傳輸數據,第一個 Datanode一小部分一小部分( 4kb)地接收數 據,將每個部分寫入本地倉庫,並且同時傳輸該部分到第二個 Datanode節點。第二個 Datanode也是這樣,邊收邊傳,一小部分一小部分地收,存儲 在本地倉庫,同時傳給第三個 Datanode,第三個 Datanode就僅僅是接收並存儲了。這就是流水線式的複製。

九、可訪問性
    HDFS給應用提供了多種訪問方式,可以通過 DFSShell通過命令行與 HDFS數據進行交互,可以通過 java API調用,也可以通過 C語言的封裝 API訪問,並且提供了瀏覽器訪問的方式。正在開發通過 WebDav協議訪問的方式。具體使用參考文檔。
十、空間的回收
1、文件的刪除和恢復
    用戶或者應用刪除某個文件,這個文件並沒有立刻從 HDFS中刪除。相反, HDFS將這個文件重命名,並轉移到 /trash目錄。當文件還在 /trash目 錄時,該文件可以被迅速地恢復。文件在 /trash中保存的時間是可配置的,當超過這個時間, Namenode就會將該文件從 namespace中刪除。 文件的刪除,也將釋放關聯該文件的數據塊。注意到,在文件被用戶刪除和 HDFS空閒空間的增加之間會有一個等待時間延遲。
    當被刪除的文件還保留在 /trash目錄中的時候,如果用戶想恢復這個文件,可以檢索瀏覽 /trash目錄並檢索該文件。 /trash目錄僅僅保存被刪除 文件的最近一次拷貝。 /trash目錄與其他文件目錄沒有什麼不同,除了一點: HDFS在該目錄上應用了一個特殊的策略來自動刪除文件,目前的默認策略是 刪除保留超過 6小時的文件,這個策略以後會定義成可配置的接口。

2 Replication因子的減小
    當某個文件的 replication因子減小, Namenode會選擇要刪除的過剩的副本。下次心跳檢測就將該信息傳遞給 Datanode Datanode就會移除相應的 block並釋放空間,同樣,在調用 setReplication方法和集羣中的空閒空間增加之間會有一個時間延遲。

參考資料:
HDFS Java API: http://hadoop.apache.org/core/docs/current/api/
HDFS source code: http://hadoop.apache.org/core/version_control.html

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