hadoopDistributed File System架構與設計

來源:互聯網
上載者:User

 

引言

HadoopDistributed File System(HDFS)被設計成適合運行在通用硬體(commodity hardware)上的Distributed File System。它和現有的Distributed File System有很多共同點。但同時,它和其他的Distributed File System的區別也是很明顯的。HDFS是一個高度容錯性的系統,適合部署在廉價的機器上。HDFS能提供高輸送量的資料訪問,非常適合大規模資料集上的應用。HDFS放寬了一部分POSIX約束,來實現流式讀取檔案系統資料的目的。HDFS在最開始是作為Apache Nutch搜尋引擎項目的基礎架構而開發的。HDFS是Apache Hadoop Core項目的一部分。這個項目的地址是http://hadoop.apache.org/core/。

前提和設計目標

硬體錯誤

硬體錯誤是常態而不是異常。HDFS可能由成百上千的伺服器所構成,每個伺服器上儲存著檔案系統的部分資料。我們面對的現實是構成系統的組件數目是巨大的,而且任一組件都有可能失效,這意味著總是有一部分HDFS的組件是不工作的。因此錯誤偵測和快速、自動的恢複是HDFS最核心的架構目標。

流式資料訪問

運行在HDFS上的應用和普通的應用不同,需要流式訪問它們的資料集。HDFS的設計中更多的考慮到了資料批處理,而不是使用者互動處理。比之資料訪問的低延遲問題,更關鍵的在於資料訪問的高輸送量。POSIX標準設定的很多硬性約束對HDFS應用系統不是必需的。為了提高資料的輸送量,在一些關鍵方面對POSIX的語義做了一些修改。

大規模資料集

運行在HDFS上的應用具有很大的資料集。HDFS上的一個典型檔案大小一般都在G位元組至T位元組。因此,HDFS被調節以支援大檔案儲存體。它應該能提供整體上高的資料傳輸頻寬,能在一個叢集裡擴充到數百個節點。一個單一的HDFS執行個體應該能支撐數以千萬計的檔案。

簡單的一致性模型

HDFS應用需要一個“一次寫入多次讀取”的檔案訪問模型。一個檔案經過建立、寫入和關閉之後就不需要改變。這一假設簡化了資料一致性問題,並且使高輸送量的資料訪問成為可能。Map/Reduce應用或者網路爬蟲應用都非常適合這個模型。目前還有計劃在將來擴充這個模型,使之支援檔案的附加寫操作。

“移動計算比移動資料更划算”

一個應用請求的計算,離它操作的資料越近就越高效,在資料達到海量層級的時候更是如此。因為這樣就能降低網路阻塞的影響,提高系統資料的輸送量。將計算移動到資料附近,比之將資料移動到應用所在顯然更好。HDFS為應用提供了將它們自己移動到資料附近的介面。

異構軟硬體平台間的可移植性

HDFS在設計的時候就考慮到平台的可移植性。這種特性方便了HDFS作為大規模資料應用平台的推廣。

Namenode 和 Datanode

HDFS採用master/slave架構。一個HDFS叢集是由一個Namenode和一定數目的Datanodes組成。Namenode是一個中心伺服器,負責管理檔案系統的名字空間(namespace)以及用戶端對檔案的訪問。叢集中的Datanode一般是一個節點一個,負責管理它所在節點上的儲存。HDFS暴露了檔案系統的名字空間,使用者能夠以檔案的形式在上面儲存資料。從內部看,一個檔案其實被分成一個或多個資料區塊,這些Block Storage在一組Datanode上。Namenode執行檔案系統的名字空間操作,比如開啟、關閉、重新命名檔案或目錄。它也負責確定資料區塊到具體Datanode節點的映射。Datanode負責處理檔案系統用戶端的讀寫請求。在Namenode的統一調度下進行資料區塊的建立、刪除和複製。

Namenode和Datanode被設計成可以在普通的商用機器上運行。這些機器一般運行著GNU/Linux作業系統(OS)。HDFS採用Java語言開發,因此任何支援Java的機器都可以部署Namenode或Datanode。由於採用了可移植性極強的Java語言,使得HDFS可以部署到多種類型的機器上。一個典型的部署情境是一台機器上只運行一個Namenode執行個體,而叢集中的其它機器分別運行一個Datanode執行個體。這種架構並不排斥在一台機器上運行多個Datanode,只不過這樣的情況比較少見。

叢集中單一Namenode的結構大大簡化了系統的架構。Namenode是所有HDFS中繼資料的仲裁者和管理者,這樣,使用者資料永遠不會流過Namenode。

檔案系統的名字空間 (namespace)

HDFS支援傳統的層次型檔案組織圖。使用者或者應用程式可以建立目錄,然後將檔案儲存在這些目錄裡。檔案系統名字空間的階層和大多數現有的檔案系統類似:使用者可以建立、刪除、移動或重新命名檔案。當前,HDFS不支援使用者磁碟配額和存取權限控制,也不支援永久連結和軟連結。但是HDFS架構並不妨礙實現這些特性。

Namenode負責維護檔案系統的名字空間,任何對檔案系統名字空間或屬性的修改都將被Namenode記錄下來。應用程式可以設定HDFS儲存的檔案的副本數目。檔案副本的數目稱為檔案的副本係數,這個資訊也是由Namenode儲存的。

資料複製

HDFS被設計成能夠在一個大叢集中跨機器可靠地儲存超大檔案。它將每個檔案儲存體成一系列的資料區塊,除了最後一個,所有的資料區塊都是同樣大小的。為了容錯,檔案的所有資料區塊都會有副本。每個檔案的資料區塊大小和副本係數都是可配置的。應用程式可以指定某個檔案的副本數目。副本係數可以在檔案建立的時候指定,也可以在之後改變。HDFS中的檔案都是一次性寫入的,並且嚴格要求在任何時候只能有一個寫入者。

Namenode全權管理資料區塊的複製,它周期性地從叢集中的每個Datanode接收心跳訊號和塊狀態報表(Blockreport)。接收到心跳訊號意味著該Datanode節點工作正常。塊狀態報表包含了一個該Datanode上所有資料區塊的列表。

副本存放: 最最開始的一步

副本的存放是HDFS可靠性和效能的關鍵。最佳化的副本存放策略是HDFS區分於其他大部分Distributed File System的重要特性。這種特性需要做大量的調優,並需要經驗的積累。HDFS採用一種稱為機架感知(rack-aware)的策略來改進資料的可靠性、可用性和網路頻寬的利用率。目前實現的副本存放策略只是在這個方向上的第一步。實現這個策略的短期目標是驗證它在生產環境下的有效性,觀察它的行為,為實現更先進的策略打下測試和研究的基礎。

大型HDFS執行個體一般運行在跨越多個機架的電腦群組成的叢集上,不同機架上的兩台機器之間的通訊需要經過交換器。在大多數情況下,同一個機架內的兩台機器間的頻寬會比不同機架的兩台機器間的頻寬大。

通過一個機架感知的過程,Namenode可以確定每個Datanode所屬的機架id。一個簡單但沒有最佳化的策略就是將副本存放在不同的機架上。這樣可以有效防止當整個機架失效時資料的丟失,並且允許讀資料的時候充分利用多個機架的頻寬。這種原則設定可以將副本均勻分布在叢集中,有利於當組件失效情況下的負載平衡。但是,因為這種策略的一個寫操作需要傳輸資料區塊到多個機架,這增加了寫的代價。

在大多數情況下,副本係數是3,HDFS的存放策略是將一個副本存放在本地機架的節點上,一個副本放在同一機架的另一個節點上,最後一個副本放在不同機架的節點上。這種策略減少了機架間的資料轉送,這就提高了寫操作的效率。機架的錯誤遠遠比節點的錯誤少,所以這個策略不會影響到資料的可靠性和可用性。於此同時,因為資料區塊只放在兩個(不是三個)不同的機架上,所以此策略減少了讀取資料時需要的網路傳輸總頻寬。在這種策略下,副本並不是均勻分布在不同的機架上。三分之一的副本在一個節點上,三分之二的副本在一個機架上,其他副本均勻分布在剩下的機架中,這一策略在不損害資料可靠性和讀取效能的情況下改進了寫的效能。

當前,這裡介紹的預設副本存放策略正在開發的過程中。

副本選擇

為了降低整體的頻寬消耗和讀取延時,HDFS會盡量讓讀取程式讀取離它最近的副本。如果在讀取程式的同一個機架上有一個副本,那麼就讀取該副本。如果一個HDFS叢集跨越多個資料中心,那麼用戶端也將首先讀本機資料中心的副本。

安全模式

Namenode啟動後會進入一個稱為安全模式的特殊狀態。處於安全模式的Namenode是不會進行資料區塊的複製的。Namenode從所有的 Datanode接收心跳訊號和塊狀態報表。塊狀態報表包括了某個Datanode所有的資料區塊列表。每個資料區塊都有一個指定的最小副本數。當Namenode檢測確認某個資料區塊的副本數目達到這個最小值,那麼該資料區塊就會被認為是副本安全(safely replicated)的;在一定百分比(這個參數可配置)的資料區塊被Namenode檢測確認是安全之後(加上一個額外的30秒等待時間),Namenode將退出安全模式狀態。接下來它會確定還有哪些資料區塊的副本沒有達到指定數目,並將這些資料區塊複製到其他Datanode上。

檔案系統中繼資料的持久化

Namenode上儲存著HDFS的名字空間。對於任何對檔案系統中繼資料產生修改的操作,Namenode都會使用一種稱為EditLog的交易記錄記錄下來。例如,在HDFS中建立一個檔案,Namenode就會在Editlog中插入一條記錄來表示;同樣地,修改檔案的副本係數也將往Editlog插入一條記錄。Namenode在本地作業系統的檔案系統中儲存這個Editlog。整個檔案系統的名字空間,包括資料區塊到檔案的映射、檔案的屬性等,都儲存在一個稱為FsImage的檔案中,這個檔案也是放在Namenode所在的本地檔案系統上。

Namenode在記憶體中儲存著整個檔案系統的名字空間和檔案資料區塊映射(Blockmap)的映像。這個關鍵的中繼資料結構設計得很緊湊,因而一個有4G記憶體的Namenode足夠支撐大量的檔案和目錄。當Namenode啟動時,它從硬碟中讀取Editlog和FsImage,將所有Editlog中的事務作用在記憶體中的FsImage上,並將這個新版本的FsImage從記憶體中儲存到本地磁碟上,然後刪除舊的Editlog,因為這箇舊的Editlog的事務都已經作用在FsImage上了。這個過程稱為一個檢查點(checkpoint)。在當前實現中,檢查點只發生在Namenode啟動時,在不久的將來將實現支援周期性的檢查點。

Datanode將HDFS資料以檔案的形式儲存在本地的檔案系統中,它並不知道有關HDFS檔案的資訊。它把每個HDFS資料區塊儲存在本地檔案系統的一個單獨的檔案中。Datanode並不在同一個目錄建立所有的檔案,實際上,它用試探的方法來確定每個目錄的最佳檔案數目,並且在適當的時候建立子目錄。在同一個目錄中建立所有的本地檔案並不是最優的選擇,這是因為本地檔案系統可能無法高效地在單個目錄中支援大量的檔案。當一個Datanode啟動時,它會掃描本地檔案系統,產生一個這些本地檔案對應的所有HDFS資料區塊的列表,然後作為報告發送到Namenode,這個報告就是塊狀態報表。

通訊協議

所有的HDFS通訊協議都是建立在TCP/IP協議之上。用戶端通過一個可配置的TCP連接埠串連到Namenode,通過ClientProtocol協議與Namenode互動。而Datanode使用DatanodeProtocol協議與Namenode互動。一個遠端程序呼叫(RPC)模型被抽象出來封裝ClientProtocol和Datanodeprotocol協議。在設計上,Namenode不會主動發起RPC,而是響應來自用戶端或 Datanode 的RPC請求。

健壯性

HDFS的主要目標就是即使在出錯的情況下也要保證資料存放區的可靠性。常見的三種出錯情況是:Namenode出錯, Datanode出錯和網路割裂(network partitions)。

磁碟資料錯誤,心跳檢測和重新複製

每個Datanode節點周期性地向Namenode發送心跳訊號。網路割裂可能導致一部分Datanode跟Namenode失去聯絡。Namenode通過心跳訊號的缺失來檢測這一情況,並將這些近期不再發送心跳訊號Datanode標記為宕機,不會再將新的IO請求發給它們。任何儲存在宕機Datanode上的資料將不再有效。Datanode的宕機可能會引起一些資料區塊的副本係數低於指定值,Namenode不斷地檢測這些需要複製的資料區塊,一旦發現就啟動複製操作。在下列情況下,可能需要重新複製:某個Datanode節點失效,某個副本遭到損壞,Datanode上的硬碟錯誤,或者檔案的副本係數增大。

叢集均衡

HDFS的架構支援資料均衡策略。如果某個Datanode節點上的空閑空間低於特定的臨界點,按照均衡策略系統就會自動地將資料從這個Datanode移動到其他閒置Datanode。當對某個檔案的請求突然增加,那麼也可能啟動一個計劃建立該檔案新的副本,並且同時重新平衡叢集中的其他資料。這些均衡策略目前還沒有實現。

資料完整性

從某個Datanode擷取的資料區塊有可能是損壞的,損壞可能是由Datanode的存放裝置錯誤、網路錯誤或者軟體bug造成的。HDFS用戶端軟體實現了對HDFS檔案內容的校正和(checksum)檢查。當用戶端建立一個新的HDFS檔案,會計算這個檔案每個資料區塊的校正和,並將校正和作為一個單獨的隱藏檔案儲存在同一個HDFS名字空間下。當用戶端擷取檔案內容後,它會檢驗從Datanode擷取的資料跟相應的校正和檔案中的校正和是否匹配,如果不匹配,用戶端可以選擇從其他Datanode擷取該資料區塊的副本。

中繼資料磁碟錯誤

FsImage和Editlog是HDFS的核心資料結構。如果這些檔案損壞了,整個HDFS執行個體都將失效。因而,Namenode可以配置成支援維護多個FsImage和Editlog的副本。任何對FsImage或者Editlog的修改,都將同步到它們的副本上。這種多副本的同步操作可能會降低Namenode每秒處理的名字空間事務數量。然而這個代價是可以接受的,因為即使HDFS的應用是資料密集的,它們也非中繼資料密集的。當Namenode重啟的時候,它會選取最近的完整的FsImage和Editlog來使用。

Namenode是HDFS叢集中的單點故障(single point of failure)所在。如果Namenode機器故障,是需要手工幹預的。目前,自動重啟或在另一台機器上做Namenode容錯移轉的功能還沒實現。

快照

快照支援某一特定時刻的資料的複本備份。利用快照,可以讓HDFS在資料損毀時恢複到過去一個已知正確的時間點。HDFS目前還不支援快照功能,但計劃在將來的版本進行支援。

資料群組織

資料區塊

HDFS被設計成支援大檔案,適用HDFS的是那些需要處理大規模的資料集的應用。這些應用都是唯寫入資料一次,但卻讀取一次或多次,並且讀取速度應能滿足流式讀取的需要。HDFS支援檔案的“一次寫入多次讀取”語義。一個典型的資料區塊大小是64MB。因而,HDFS中的檔案總是按照64M被切分成不同的塊,每個塊儘可能地儲存於不同的Datanode中。

Staging

用戶端建立檔案的請求其實並沒有立即發送給Namenode,事實上,在剛開始階段HDFS用戶端會先將檔案資料緩衝到本地的一個臨時檔案。應用程式的寫操作被透明地重新導向到這個臨時檔案。當這個臨時檔案累積的資料量超過一個資料區塊的大小,用戶端才會聯絡Namenode。Namenode將檔案名稱插入檔案系統的階層中,並且分配一個資料區塊給它。然後返回Datanode的標識符和目標資料區塊給用戶端。接著用戶端將這塊資料從本地臨時檔案上傳到指定的Datanode上。當檔案關閉時,在臨時檔案中剩餘的沒有上傳的資料也會傳輸到指定的Datanode上。然後用戶端告訴Namenode檔案已經關閉。此時Namenode才將檔案建立操作提交到日誌裡進行儲存。如果Namenode在檔案關閉前宕機了,則該檔案將丟失。

上述方法是對在HDFS上啟動並執行目標應用進行認真考慮後得到的結果。這些應用需要進行檔案的流式寫入。如果不採用用戶端緩衝,由於網路速度和網路堵塞會對吞估量造成比較大的影響。這種方法並不是沒有先例的,早期的檔案系統,比如AFS,就用用戶端緩衝來提高效能。為了達到更高的資料上傳效率,已經放鬆了POSIX標準的要求。

流水線複製

當用戶端向HDFS檔案寫入資料的時候,一開始是寫到本地臨時檔案中。假設該檔案的副本係數設定為3,當本地臨時檔案累積到一個資料區塊的大小時,用戶端會從Namenode擷取一個Datanode列表用於存放副本。然後用戶端開始向第一個Datanode傳輸資料,第一個Datanode一小部分一小部分(4 KB)地接收資料,將每一部分寫入本地倉庫,並同時傳輸該部分到列表中第二個Datanode節點。第二個Datanode也是這樣,一小部分一小部分地接收資料,寫入本地倉庫,並同時傳給第三個Datanode。最後,第三個Datanode接收資料並儲存在本地。因此,Datanode能流水線式地從前一個節點接收資料,並在同時轉寄給下一個節點,資料以流水線的方式從前一個Datanode複製到下一個。

可訪問性

HDFS給應用提供了多種訪問方式。使用者可以通過Java API介面訪問,也可以通過C語言的封裝API訪問,還可以通過瀏覽器的方式訪問HDFS中的檔案。通過WebDAV協議訪問的方式正在開發中。

DFSShell

HDFS以檔案和目錄的形式組織使用者資料。它提供了一個命令列的介面(DFSShell)讓使用者與HDFS中的資料進行互動。命令的文法和使用者熟悉的其他shell(例如 bash, csh)工具類似。下面是一些動作/命令的樣本:

動作 命令
建立一個名為 /foodir 的目錄 bin/hadoop dfs -mkdir /foodir
建立一個名為 /foodir 的目錄 bin/hadoop dfs -mkdir /foodir
查看名為 /foodir/myfile.txt 的檔案內容 bin/hadoop dfs -cat /foodir/myfile.txt

DFSShell 可以用在那些通過指令碼語言和檔案系統進行互動的應用程式上。

DFSAdmin

DFSAdmin 命令用來管理HDFS叢集。這些命令只有HDSF的管理員才能使用。下面是一些動作/命令的樣本:

動作 命令
將叢集置於安全模式 bin/hadoop dfsadmin -safemode enter
顯示Datanode列表 bin/hadoop dfsadmin -report
使Datanode節點 datanodename退役 bin/hadoop dfsadmin -decommission datanodename

瀏覽器介面

一個典型的HDFS安裝會在一個可配置的TCP連接埠開啟一個Web伺服器用於暴露HDFS的名字空間。使用者可以用瀏覽器來瀏覽HDFS的名字空間和查看檔案的內容。

儲存空間回收

檔案的刪除和恢複

當使用者或應用程式刪除某個檔案時,這個檔案並沒有立刻從HDFS中刪除。實際上,HDFS會將這個檔案重新命名轉移到/trash目錄。只要檔案還在/trash目錄中,該檔案就可以被迅速地恢複。檔案在/trash中儲存的時間是可配置的,當超過這個時間時,Namenode就會將該檔案從名字空間中刪除。刪除檔案會使得該檔案相關的資料區塊被釋放。注意,從使用者刪除檔案到HDFS空閑空間的增加之間會有一定時間的延遲。

只要被刪除的檔案還在/trash目錄中,使用者就可以恢複這個檔案。如果使用者想恢複被刪除的檔案,他/她可以瀏覽/trash目錄找回該檔案。/trash目錄僅僅儲存被刪除檔案的最後副本。/trash目錄與其他的目錄沒有什麼區別,除了一點:在該目錄上HDFS會應用一個特殊策略來自動刪除檔案。目前的預設策略是刪除/trash中保留時間超過6小時的檔案。將來,這個策略可以通過一個被良好定義的介面配置。

減少副本係數

當一個檔案的副本係數被減小後,Namenode會選擇過剩的副本刪除。下次心跳檢測時會將該資訊傳遞給Datanode。Datanode遂即移除相應的資料區塊,叢集中的空閑空間加大。同樣,在調用setReplication API結束和叢集中空閑空間增加間會有一定的延遲。

 

 

HDFS Java API: http://hadoop.apache.org/core/docs/current/api/

HDFS 原始碼: http://hadoop.apache.org/core/version_control.html

by Dhruba Borthakur

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.