hadoop分布式架構和設計


引言

Hadoop分布式文件系統(HDFS)被設計成適合執行在通用硬件(commodity hardware)上的分布式文件系統。它和現有的分布式文件系統有非常多共同點。但同一時候,它和其它的分布式文件系統的差別也是非常明顯的。HDFS是一個高度容錯性的系統,適合部署在便宜的機器上。HDFS能提供高吞吐量的數據訪問。非常適合大規模數據集上的應用。

HDFS放寬了一部分POSIX約束,來實現流式讀取文件系統數據的目的。

HDFS在最開始是作為Apache Nutch搜索引擎項目的基礎架構而開發的。

HDFS是Apache Hadoop Core項目的一部分。

這個項目的地址是http://hadoop.apache.org/core/。     

前提和設計目標

硬件錯誤

硬件錯誤是常態而不是異常。

HDFS可能由成百上千的server所構成,每一個server上存儲着文件系統的部分數據。我們面對的現實是構成系統的組件數目是巨大的。並且任一組件都有可能失效。這意味着總是有一部分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是一個中心server,負責管理文件系統的名字空間(namespace)以及client對文件的訪問。集群中的Datanode通常是一個節點一個,負責管理它所在節點上的存儲。HDFS暴露了文件系統的名字空間,用戶可以以文件的形式在上面存儲數據。從內部看,一個文件事實上被分成一個或多個數據塊,這些塊存儲在一組Datanode上。Namenode運行文件系統的名字空間操作,比方打開、關閉、重命名文件或文件夾。

它也負責確定數據塊到詳細Datanode節點的映射。Datanode負責處理文件系統client的讀寫請求。在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區分於其它大部分分布式文件系統的重要特性。這樣的特性須要做大量的調優,並須要經驗的積累。

HDFS採用一種稱為機架感知(rack-aware)的策略來改進數據的可靠性、可用性和網絡帶寬的利用率。眼下實現的副本存放策略僅僅是在這個方向上的第一步。

實現這個策略的短期目標是驗證它在生產環境下的有效性。觀察它的行為,為實現更先進的策略打下測試和研究的基礎。

        

大型HDFS實例一般執行在跨越多個機架的計算機組成的集群上,不同機架上的兩台機器之間的通訊須要經過交換機。在大多數情況下。同一個機架內的兩台機器間的帶寬會比不同機架的兩台機器間的帶寬大。

               

        通過一個機架感知的過程,Namenode能夠確定每一個Datanode所屬的機架id。一個簡單但沒有優化的策略就是將副本存放在不同的機架上。這樣能夠有效防止當整個機架失效時數據的丟失,而且同意讀數據的時候充分利用多個機架的帶寬。這樣的策略設置能夠將副本均勻分布在集群中,有利於當組件失效情況下的負載均衡。可是,由於這樣的策略的一個寫操作須要數據傳輸塊到多個機架,這添加了寫的代價。

        

        在大多數情況下。副本系數是3。HDFS的存放策略是將一個副本存放在本地機架的節點上,一個副本放在同一機架的還有一個節點上,最后一個副本放在不同機架的節點上。這樣的策略降低了機架間的傳輸數據。這就提高了寫操作的效率。機架的錯誤遠遠比節點的錯誤少,所以這個策略不會影響到數據的可靠性和可用性。於此同一時候,由於數據塊僅僅放在兩個(不是三個)不同的機架上,所以此策略降低了讀取數據時須要的網絡傳輸總帶寬。在這樣的策略下。副本並非均勻分布在不同的機架上。三分之中的一個的副本在一個節點上,三分之二的副本在一個機架上,其它副本均勻分布在剩下的機架中。這一策略在不損害數據可靠性和讀取性能的情況下改進了寫的性能。       

        當前,這里介紹的默認副本存放策略正在開發的過程中。

       

副本選擇

        為了減少總體的帶寬消耗和讀取延時,HDFS會盡量讓讀取程序讀取離它近期的副本。假設在讀取程序的同一個機架上有一個副本,那么就讀取該副本。假設一個HDFS集群跨越多個數據中心,那么client也將首先讀本地數據中心的副本。       

安全模式

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協議之上。client通過一個可配置的TCPport連接到Namenode,通過ClientProtocol協議與Namenode交互。而Datanode使用DatanodeProtocol協議與Namenode交互。一個遠程過程調用(RPC)模型被抽象出來封裝ClientProtocol和Datanodeprotocol協議。在設計上,Namenode不會主動發起RPC,而是響應來自client或 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造成的。

HDFSclient軟件實現了對HDFS文件內容的校驗和(checksum)檢查。當client創建一個新的HDFS文件,會計算這個文件每一個數據塊的校驗和,並將校驗和作為一個單獨的隱藏文件保存在同一個HDFS名字空間下。當client獲取文件內容后,它會檢驗從Datanode獲取的數據跟對應的校驗和文件里的校驗和是否匹配。假設不匹配,client能夠選擇從其它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

client創建文件的請求其實並沒有馬上發送給Namenode。其實,在剛開始階段HDFSclient會先將文件數據緩存到本地的一個暫時文件。應用程序的寫操作被透明地重定向到這個暫時文件。當這個暫時文件累積的數據量超過一個數據塊的大小。client才會聯系Namenode。Namenode將文件名稱插入文件系統的層次結構中,而且分配一個數據塊給它。

然后返回Datanode的標識符和目標數據塊給client。接着client將這塊數據從本地暫時文件上傳到指定的Datanode上。當文件關閉時,在暫時文件里剩余的沒有上傳的數據也會傳輸到指定的Datanode上。

然后client告訴Namenode文件已經關閉。此時Namenode才將文件創建操作提交到日志里進行存儲。

假設Namenode在文件關閉前宕機了,則該文件將丟失。       

        上述方法是對在HDFS上執行的目標應用進行認真考慮后得到的結果。這些應用須要進行文件的流式寫入。假設不採用client緩存。因為網絡速度和網絡阻塞會對吞估量造成比較大的影響。這樣的方法並非沒有先例的,早期的文件系統,比方AFS,就用client緩存來提高性能。為了達到更高的數據上傳效率,已經放松了POSIX標准的要求。       

流水線復制

        當client向HDFS文件寫入數據的時候。一開始是寫到本地暫時文件里。如果該文件的副本系數設置為3,當本地暫時文件累積到一個數據塊的大小時。client會從Namenode獲取一個Datanode列表用於存放副本。

然后client開始向第一個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安裝會在一個可配置的TCPport開啟一個Webserver用於暴露HDFS的名字空間。

用戶能夠用瀏覽器來瀏覽HDFS的名字空間和查看文件的內容。      

存儲空間回收

文件的刪除和恢復

       當用戶或應用程序刪除某個文件時,這個文件並沒有立馬從HDFS中刪除。實際上,HDFS會將這個文件重命名轉移到/trash文件夾。

僅僅要文件還在/trash文件夾中,該文件就能夠被迅速地恢復。

文件在/trash中保存的時間是可配置的,當超過這個時間時。Namenode就會將該文件從名字空間中刪除。刪除文件會使得該文件相關的數據塊被釋放。注意,從用戶刪除文件到HDFS空暇空間的添加之間會有一定時間的延遲。

只要被刪除的文件還在/trash文件夾中。用戶就能夠恢復這個文件。

假設用戶想恢復被刪除的文件,他/她能夠瀏覽/trash文件夾找回該文件。/trash文件夾只保存被刪除文件的最后副本。/trash文件夾與其它的文件夾沒有什么差別,除了一點:在該文件夾上HDFS會應用一個特殊策略來自己主動刪除文件。眼下的默認策略是刪除/trash中保留時間超過6小時的文件。將來。這個策略能夠通過一個被良好定義的接口配置。       

降低副本系數

        當一個文件的副本系數被減小后。Namenode會選擇過剩的副本刪除。

下次心跳檢測時會將該信息傳遞給Datanode。Datanode遂即移除對應的數據塊,集群中的空暇空間加大。相同,在調用setReplication API結束和集群中空暇空間添加間會有一定的延遲。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM