介紹
Hadoop分布式文件系統( <acronym title="Hadoop分布式文件系統" style="cursor: help;">HDFS</acronym> )是一種分布式文件系統,設計用于在商品硬件上運行。它與現有的分布式文件系統有許多相似之處。但是,與其他分布式文件系統的差異很大。HDFS具有高度容錯能力,旨在部署在低成本硬件上。HDFS提供對應用程序數據的高吞吐量訪問,適用于具有大型數據集的應用程序。HDFS放寬了一些POSIX要求,以啟用對文件系統數據的流式訪問。HDFS最初是作為Apache Nutch網絡搜索引擎項目的基礎架構而構建的。HDFS現在是一個Apache Hadoop子項目。項目URL是http://hadoop.apache.org/hdfs/ 。
假設和目標
硬件故障
硬件故障是常態而非例外。一個HDFS實例可能由數百或數千個服務器機器組成,每個服務器機器都存儲部分文件系統的數據。事實上,有大量的組件,并且每個組件具有不可忽略的失敗概率,這意味著HDFS的某個組件始終不起作用。因此,檢測故障并快速自動恢復是HDFS的核心架構目標。
流數據訪問
在HDFS上運行的應用程序需要流式訪問其數據集。它們不是通常運行在通用文件系統上的通用應用程序。HDFS的設計更多用于批處理,而不是用戶交互式使用。重點是數據訪問的高吞吐量,而不是數據訪問的低延遲。POSIX強加了HDFS所針對的應用程序所不需要的許多硬性要求。一些關鍵領域的POSIX語義已被舍棄以提高數據吞吐率。
大型數據集
在HDFS上運行的應用程序具有大量數據集。HDFS中的典型文件大小為千兆字節(gigabytes)至兆兆字節(terabytes)。因此,HDFS被調整為支持大文件。它應該為單個群集中的數百個節點提供高聚合數據帶寬和規模(high aggregate data bandwidth and scale)。它應該支持單個實例中的數千萬個文件。
簡單一致性模型
HDFS應用程序需要一次寫入多次讀取多個文件訪問模型。一次創建,寫入和關閉的文件不需要更改。這種假設簡化了數據一致性問題并實現了高吞吐量數據訪問。MapReduce應用程序或Web爬蟲應用程序完全符合此模型。有一個計劃來支持未來對文件的追加寫入。
“移動計算比移動數據便宜”
如果應用程序在其操作的數據附近執行,則應用程序所請求的計算效率會更高。當數據集的大小很大時尤其如此。這可以最大限度地減少網絡擁塞并提高系統的整體吞吐量。我們的假設是,將計算遷移到更接近數據所在的位置通常會更好,而不是將數據移動到應用程序正在運行的位置。HDFS為應用程序提供接口,使它們更接近數據所在的位置。
跨異構硬件和軟件平臺的可移植性
HDFS的設計很容易從一個平臺移植到另一個平臺。這有利于廣泛采用HDFS作為大量應用選擇的平臺。
NameNode和DataNodes
HDFS具有主/從架構。一個HDFS集群包含一個NameNode,一個主服務器,用于管理文件系統名稱空間并管理客戶端對文件的訪問。此外,還有許多DataNode,通常是群集中的每個節點一個DataNode,用于管理連接到它們所運行的節點的存儲。HDFS公開文件系統名稱空間并允許用戶數據存儲在文件中。在內部,文件被分成一個或多個塊,這些塊存儲在一組DataNode中。NameNode執行文件系統命名空間操作,如打開,關閉和重命名文件和目錄。它還確定塊到DataNode的映射。DataNode負責提供來自文件系統客戶端的讀取和寫入請求。DataNode還根據來自NameNode的指令執行數據塊創建,刪除和復制。
NameNode和DataNode是設計用于在商品機器上運行的軟件。這些機器通常運行GNU / Linux操作系統( <acronym title="操作系統" style="cursor: help;">OS</acronym> )。HDFS使用Java語言構建;任何支持Java的機器都可以運行NameNode或DataNode軟件。使用高度可移植的Java語言意味著HDFS可以部署在各種機器上。典型的部署有一臺只運行NameNode軟件的專用機器。群集中的每臺其他機器運行DataNode軟件的一個實例。該體系結構不排除在同一臺計算機上運行多個DataNode,但在實際部署中很少出現這種情況。
集群中單個NameNode的存在極大地簡化了系統的體系結構。NameNode是所有HDFS元數據的仲裁者和存儲庫。該系統的設計方式是用戶數據永遠不會流經NameNode。
文件系統命名空間
HDFS支持傳統的分層文件組織。用戶或應用程序可以在這些目錄內創建目錄并存儲文件。文件系統名稱空間層次與大多數其他現有文件系統類似;可以創建和刪除文件,將文件從一個目錄移動到另一個目錄,或者重命名文件。HDFS尚未實現用戶配額。HDFS不支持硬鏈接或軟鏈接。但是,HDFS體系結構并不排除實現這些功能。
NameNode維護文件系統名稱空間。NameNode記錄對文件系統名稱空間或其屬性的任何更改。應用程序可以指定HDFS應該維護的文件的副本數量。文件的副本數稱為該文件的復制因子。這些信息由NameNode存儲。
數據復制
HDFS旨在可靠地在大型群集中的機器上存儲超大型文件。它將每個文件存儲為一系列的塊;文件中除最后一個塊之外的所有塊都具有相同的大小。文件的塊被復制以實現容錯。塊大小和復制因子可以針對每個文件進行配置。應用程序可以指定文件的副本數量。可以在文件創建時指定復制因子,并可稍后進行更改。HDFS中的文件是一次寫入的,并且在任何時候都嚴格限定一個寫入者。
NameNode做出關于塊復制的所有決定。它定期從集群中的每個DataNode接收Heartbeat和Blockreport。收到Heartbeat意味著DataNode運行正常。Blockreport包含DataNode上所有塊的列表。
復制品安置:第一個嬰兒步驟
復制品的放置對于HDFS的可靠性和性能至關重要。優化副本位置可將HDFS與大多數其他分布式文件系統區分開來。這是一項需要大量調整和體驗的功能。機架感知復制品放置策略(rack-aware replica placement policy)的目的是提高數據可靠性,可用性和網絡帶寬利用率。復制品放置策略的當前實現是朝這個方向的第一步。實施這項策略的短期目標是在生產系統上對其進行驗證,更多地了解其行為,并為測試和研究更復雜的策略奠定基礎。
大型HDFS實例運行在通常分布在多個機架上的一組計算機上。不同機架中兩個節點之間的通信必須通過交換機。在大多數情況下,同一機架中機器之間的網絡帶寬大于不同機架中機器之間的網絡帶寬。
NameNode通過Hadoop Rack Awareness中概述的過程確定每個DataNode所屬的機架標識。一個簡單但非最佳的策略是將副本放在不同的機架上。這可以防止整個機架出現故障時丟失數據,并允許在讀取數據時從多個機架使用帶寬。此策略在集群中均勻分配副本,以便輕松平衡組件故障時的負載。但是,此策略會增加寫入成本,因為寫入需要將塊傳輸到多個機架。
對于常見情況,當復制因子為3時,HDFS的放置策略是將一個副本放在本地機架中的一個節點上,另一個放在另一個(遠程)機架中的節點上,并將最后一個放在相同的遠程機架的不同節點上。該策略可以減少機架間寫入流量,這通常會提高寫入性能。機架故障的機會遠遠小于節點故障的機會;此策略不會影響數據可靠性和可用性保證。但是,它確實降低了讀取數據時使用的總體網絡帶寬,因為塊僅放置在兩個不同的機架中,而不是三個。使用此策略,文件的副本不會均勻分布在機架上。三分之一的副本位于一個節點上,三分之二的副本位于一個機架上,另外三分之一的副本均勻分布在其余機架上。此策略可提高寫入性能,而不會影響數據可靠性或讀取性能。
此處描述的當前默認副本放置策略是一項正在進行的工作。
副本選擇
為了最大限度地降低全局帶寬消耗和讀取延遲,HDFS會嘗試滿足最接近讀者的副本的讀取請求。如果在讀者節點的同一機架上存在副本,則該副本優先滿足讀取請求。如果HDFS集群跨越多個數據中心,則駐留在本地數據中心的副本優先于任何遠程副本。
安全模式
在啟動時,NameNode進入一個稱為Safemode的特殊狀態。當NameNode處于安全模式狀態時,不會發生數據塊的復制。NameNode接收來自DataNode的Heartbeat和Blockreport消息。Blockreport包含DataNode托管的數據塊列表。每個塊都有指定的最小數量的副本。當該數據塊的最小副本數已與NameNode簽入時,該塊被認為是安全復制的。在安全復制數據塊的可配置百分比簽入NameNode(再加上30秒)之后,NameNode退出安全模式狀態。然后確定(如果有的話)仍然少于指定的副本數量的數據塊的列表。NameNode然后將這些塊復制到其他DataNode。
文件系統元數據的持久性
HDFS名稱空間由NameNode存儲。NameNode使用名為EditLog的事務日志來持久記錄文件系統元數據發生的所有更改。例如,在HDFS中創建一個新文件會導致NameNode向EditLog中插入一條記錄,指出這一點。同樣,更改文件的復制因子會導致將新記錄插入到EditLog中。NameNode使用其本地主機OS文件系統中的文件來存儲EditLog。整個文件系統名稱空間(包括塊到文件和文件系統屬性的映射)存儲在名為FsImage的文件中。FsImage也作為文件存儲在NameNode的本地文件系統中。
NameNode將整個文件系統名稱空間和文件Blockmap的映像保存在內存中。這個關鍵的元數據項目設計得很緊湊,這樣一個具有4GB RAM的NameNode足以支持大量的文件和目錄。當NameNode啟動時,它從磁盤讀取FsImage和EditLog,將EditLog中的所有事務應用到FsImage的內存中表示,并將此新版本刷新到磁盤上的新FsImage中。它可以截斷舊的EditLog,因為它的事務已經被應用到持久的FsImage。這個過程被稱為檢查點。在當前的實現中,只有在NameNode啟動時才會出現檢查點。正在開展工作以支持不久的將來的定期檢查點。
DataNode將HDFS數據存儲在本地文件系統中的文件中。DataNode沒有關于HDFS文件的知識。它將每個HDFS數據塊存儲在本地文件系統中的單獨文件中。DataNode不會在同一目錄中創建所有文件。相反,它使用啟發式來確定每個目錄的最佳文件數量并適當地創建子目錄。在同一目錄中創建所有本地文件并不是最佳選擇,因為本地文件系統可能無法有效地支持單個目錄中的大量文件。當DataNode啟動時,它掃描其本地文件系統,生成與每個本地文件相對應的所有HDFS數據塊的列表,并將此報告發送給NameNode:這是Blockreport。
通信協議
所有HDFS通信協議都在TCP / IP協議之上進行分層。客戶端建立到NameNode機器上可配置<acronym title="傳輸控制協議" style="cursor: help;">TCP</acronym>端口的連接。它與NameNode按照ClientProtocol交談。DataNode使用DataNode協議與NameNode進行通信。遠程過程調用( <acronym title="遠程過程調用" style="cursor: help;">RPC</acronym> )抽象包裝了客戶端協議和DataNode協議。根據設計,NameNode永遠不會啟動任何RPC。相反,它只響應DataNode或客戶端發出的RPC請求。
穩健性
HDFS的主要目標是即使在出現故障時也能可靠地存儲數據。三種常見類型的故障是NameNode故障,DataNode故障和網絡分區。
數據磁盤故障,心跳和重新復制
每個DataNode定期向NameNode發送一個Heartbeat消息。網絡分區可能會導致一部分DataNode失去與NameNode的連接。NameNode通過缺少Heartbeat消息來檢測這種情況。NameNode將沒有最近Heartbeats的DataNode標記為死亡,并且不會向它們轉發任何新的<acronym title="輸入輸出" style="cursor: help;">IO</acronym>請求。任何注冊到死亡DataNode的數據不再可用于HDFS。DataNode死亡可能導致某些塊的復制因子降到其指定值以下。NameNode會不斷跟蹤哪些塊需要復制,并在需要時啟動復制。重新復制的必要性可能由于許多原因而產生:DataNode可能變得不可用,副本可能會損壞,DataNode上的硬盤可能會失敗,或者文件的復制因子可能會增加。
群集重新平衡
HDFS架構與數據重新平衡方案兼容。如果DataNode上的可用空間低于某個閾值,則方案可能會自動將數據從一個DataNode移動到另一個DataNode。在特定文件突然高需求的情況下,一個方案可能會動態創建額外的副本并重新平衡群集中的其他數據。這些類型的數據重新平衡方案尚未實施。
數據的完整性
從DataNode獲取的數據塊可能已損壞。由于存儲設備故障,網絡故障或軟件錯誤,可能會發生此損壞。HDFS客戶端軟件對HDFS文件的內容執行校驗和檢查。當客戶端創建HDFS文件時,它會計算文件每個塊的校驗和,并將這些校驗和存儲在同一個HDFS名稱空間中的單獨隱藏文件中。當客戶端檢索文件內容時,它會驗證從每個DataNode收到的數據是否與存儲在相關校驗和文件中的校驗和相匹配。如果不是,那么客戶端可以選擇從另一個具有該塊的副本的DataNode中檢索該塊。
元數據磁盤失敗
FsImage和EditLog是HDFS的中心數據結構。這些文件的損壞可能會導致HDFS實例失效。由于這個原因,NameNode可以配置為支持維護FsImage和EditLog的多個副本。對FsImage或EditLog的任何更新都會導致每個FsImages和EditLog同步更新。同步更新FsImage和EditLog的多個副本可能會降低NameNode每秒可支持的名稱空間事務處理速度。但是,這種降級是可以接受的,因為即使HDFS應用程序本質上是非常密集的數據,它們也不是元數據密集型的。當NameNode重新啟動時,它會選擇最新的一致的FsImage和EditLog來使用。
NameNode機器是HDFS群集的單點故障。如果NameNode機器出現故障,則需要手動干預。目前,不支持NameNode軟件自動重新啟動和故障切換到另一臺機器。
快照
快照支持在特定時刻存儲數據副本。快照功能的一種用法可能是將損壞的HDFS實例回滾到先前已知的良好時間點。HDFS目前不支持快照,但將在未來的版本中支持。
數據組織
數據塊
HDFS旨在支持非常大的文件。與HDFS兼容的應用程序是處理大型數據集的應用程序。這些應用程序只寫入其數據一次,但他們讀取一次或多次,并要求在流速下滿足這些讀取。HDFS支持在文件上一次寫入多次讀取語義。HDFS使用的典型塊大小為64 MB。因此,HDFS文件被分成64 MB的塊,如果可能的話,每個塊將駐留在不同的DataNode上。
分期(Staging)
客戶端創建文件的請求不會立即到達NameNode。實際上,HDFS客戶端最初將文件數據緩存到臨時本地文件中。應用程序寫入被透明地重定向到這個臨時的本地文件。當本地文件累積超過一個HDFS塊大小的數據時,客戶端會聯系NameNode。NameNode將文件名插入到文件系統層次結構中,并為其分配一個數據塊。NameNode用DataNode的標識和目標數據塊響應客戶請求。然后客戶端將本地臨時文件中的數據塊刷新到指定的DataNode。當文件關閉時,臨時本地文件中剩余的未刷新數據將傳輸到DataNode。客戶端然后告訴NameNode文件已關閉。此時,NameNode將文件創建操作提交到持久存儲區。如果NameNode在文件關閉之前死亡,則文件丟失。
在仔細考慮在HDFS上運行的目標應用程序后,采用了上述方法。這些應用程序需要流式寫入文件。如果客戶端在沒有任何客戶端緩沖的情況下直接寫入遠程文件,則網絡速度和網絡擁塞會嚴重影響吞吐量。這種做法并非沒有先例。早期的分布式文件系統(例如<acronym title="安德魯(Andrew)文件系統" style="cursor: help;">AFS</acronym> )使用客戶端緩存來提高性能。POSIX的要求已經放寬,以實現更高的數據上傳性能。
復制流水線
當客戶端將數據寫入HDFS文件時,首先將數據寫入本地文件,如前一節所述。假設HDFS文件的復制因子為3。當本地文件累積完整的用戶數據塊時,客戶端從NameNode中檢索DataNode列表。該列表包含將承載該塊的副本的DataNode。客戶端然后將數據塊刷新到第一個DataNode。第一個DataNode開始以小部分(4 KB)接收數據,將每個部分寫入其本地存儲庫并將該部分傳輸到列表中的第二個DataNode。第二個DataNode反過來開始接收數據塊的每個部分,將該部分寫入其存儲庫,然后將該部分刷新到第三個DataNode。最后,第三個DataNode將數據寫入其本地存儲庫。因此,DataNode可以從流水線中的前一個接收數據,并且同時將數據轉發到流水線中的下一個數據。因此,數據從一個DataNode流水到下一個。
無障礙(Accessibility)
HDFS可以通過許多不同的方式從應用程序中訪問。從本質上講,HDFS為應用程序提供了一個Java API 。此Java API的C語言包裝器也可用。另外,還可以使用HTTP瀏覽器瀏覽HDFS實例的文件。正在進行工作,通過<acronym title="基于Web的分布式創作和版本控制" style="cursor: help;">WebDAV</acronym>協議公開HDFS。
FS Shell
HDFS允許用戶數據以文件和目錄的形式組織。它提供了一個名為FS shell的命令行界面,可讓用戶與HDFS中的數據進行交互。這個命令集的語法類似于用戶已經熟悉的其他shell(例如bash,csh)。以下是一些示例操作/命令對:
| 行動 | 命令 |
| 創建一個名為/ foodir的目錄 | bin / hadoop dfs -mkdir / foodir |
| 刪除名為/ foodir的目錄 | bin / hadoop dfs -rmr / foodir |
| 查看名為/foodir/myfile.txt的文件的內容 | bin / hadoop dfs -cat /foodir/myfile.txt |
FS Shell針對需要腳本語言與存儲數據進行交互的應用程序。
DFSAdmin
DFSAdmin命令集用于管理HDFS集群。這些是僅由HDFS管理員使用的命令。以下是一些示例操作/命令對:
| 行動 | 命令 |
| 將群集置于Safemode | bin / hadoop dfsadmin -safemode進入 |
| 生成DataNode列表 | bin / hadoop dfsadmin -report |
| 重新投放或停用DataNode(s) | bin / hadoop dfsadmin -refreshNodes |
瀏覽器界面
典型的HDFS安裝將Web服務器配置為通過可配置的TCP端口公開HDFS名稱空間。這允許用戶使用Web瀏覽器瀏覽HDFS名稱空間并查看其文件的內容。
空間回收
文件刪除和取消刪除
當文件被用戶或應用程序刪除時,它不會立即從HDFS中刪除。相反,HDFS首先將其重命名為/ trash目錄中的文件。只要文件保持在/垃圾箱中,該文件可以快速恢復。文件保留在/垃圾箱中一段可配置的時間。在/ trash中生命期滿后,NameNode將文件從HDFS名稱空間中刪除。刪除文件會導致與文件關聯的塊被釋放。請注意,用戶刪除文件的時間與HDFS中相應增加可用空間的時間之間可能存在明顯的時間延遲。
用戶可以在刪除文件后取消刪除文件,只要文件保留在/ trash目錄中即可。如果用戶想要取消刪除他/她已刪除的文件,他/她可以瀏覽/垃圾目錄并檢索文件。/ trash目錄僅包含已刪除文件的最新副本。/ trash目錄就像具有一個特殊功能的任何其他目錄一樣:HDFS應用指定策略自動從該目錄中刪除文件。當前的默認策略是從/垃圾桶中刪除超過6個小時的文件。將來,這個策略將通過一個定義良好的界面進行配置。
降低復制因子
當文件的復制因子減少時,NameNode選擇可以刪除的多余副本。下一個Heartbeat將此信息傳輸到DataNode。DataNode然后刪除相應的塊,并在群集中出現相應的可用空間。再一次, setReplication API調用完成和群集中可用空間的出現之間可能存在時間延遲。
參考
HDFS Java API: http : //hadoop.apache.org/core/docs/current/api/
HDFS源代碼: http : //hadoop.apache.org/hdfs/version_control.html
由Dhruba Borthakur提供