Apache Hadoop項目爲高可用、可擴展、分佈式計算開發開源軟件。Apache Hadoop軟件庫是一個平臺,它使用簡單的編程模型讓跨機器上大數據量的分佈式計算變得簡單。 它旨在從單個服務器擴展到數千臺計算機,每臺計算機都提供本地計算和存儲。庫自己被設計用來在軟件層面檢測和處理故障,而不是依賴硬件來提供高可用性,所以,在計算機集羣之上提供高可用性服務,每一個計算機均可能容易出現故障。html
HDFS是一個被設計用來運行在商用機器上的分佈式文件系統。它跟現有的分佈式文件系統有不少類似之處,可是,區別也很大。HDFS容錯率高,而且被設計爲部署在廉價機器上。HDFS提供對應用程序數據的高吞吐量訪問,適用於具備大型數據集的應用程序。HDFS放寬了一些POSIX要求,以實現對文件系統數據的流式訪問。HDFS最開始被構建是用來做爲Nutch搜索引擎項目的基礎設施。HDFS是Apache hadoop核心項目的一部分。項目地址:hadoop.apache.org/node
硬件故障很常見。一個HDFS示例應該是包含成百上千臺服務器,每臺服務器保存文件系統的部分數據。事實上,存在大量組件而且每一個組件都有可能出現故障,這意外着有些組件可能一直沒法正常工做。所以,檢測故障而且自動從故障中快速恢復是HDFS架構的核心目標。linux
在HDFS上運行的程序須要對其數據集進行流式訪問。它們不是運行在普通文件系統上的普通應用程序。HDFS被設計更可能是做爲批處理來使用,而不是用戶的交互式使用。重點是數據訪問的高吞吐量而不是數據訪問的低延遲。POSIX強加了許多針對HDFS的應用程序不須要的硬性要求。web
運行在HDFS上的程序用戶大量的數據集。HDFS中,一個普通文件能夠達到千兆到太字節。所以,HDFS調整爲支持大文件。它應該提供高聚合數據帶寬並擴展到單個集羣中的數百個節點。 它應該在單個實例中支持數千萬個文件。算法
HDFS程序須要一個一次寫入屢次讀取的文件訪問模型。一次建立、寫入和關閉的文件,除了追加和截斷以外,不須要更改。能夠在文件尾部追加內容,可是不能在任意位置進行修改。這種假設簡化了一致性問題,而且提升了數據訪問的吞吐量。這種模型很是適合Mapreduce程序以及網絡爬蟲。shell
當計算所須要的數據距離計算越近時,計算的效率越高,當數據量越大時,這個效率提高更明顯。越少的網絡阻塞越能提升系統總體的吞吐量。這樣,咱們能夠認爲,將計算遷移到數據附近比將數據遷移到計算附近更高效。HHDFS爲應用程序提供了接口,使其自身更靠近數據所在的位置。apache
HDFS被設計成易於從一個平臺移植到另外一個平臺。這有助於HDFS的普及。編程
HDFS有一個主從架構。一個HDFS集羣包含一個Namenode,Namenode管理文件系統的命名空間以及調整客戶端對文件的訪問。此外,還有必定數量的Datanode,集羣中一般一個節點一個Datanode,用來管理其運行節點上的存儲。HDFS公開文件系統命名空間,並容許用戶數據存儲在文件中。集羣內部,一個文件被分紅一個或多個blocks而且這些blocks存儲在一些Datanode上。Namenode執行文件系統命名空間操做,例如打開、關閉、重命名文件和文件夾。Namenode還決定blocks到Datanode的映射。Datanode負責服務於系統客戶端的讀和寫。DataNode還根據NameNode的指令執行塊建立,刪除和複製。 api
Namenode和Datanode時設計用於運行在商用機器上的軟件。這些機器一般運行linux操做系統。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全權負責。Namenode按期接收集羣中Datanode的心跳和塊信息報告。接收到心跳代表Datanode正常工做。塊信息報告(Blockreport)包含DataNode上全部塊的列表。
副本的選址對HDFS的可靠性和性能起到相當重要的做用。優化副本的選址使HDFS區別於其餘分佈式文件系統。這是一個須要大量調試和經驗的特性。機架感知式的選址策略的目標是爲了提供數據可靠性、可用性以及帶寬利用率。目前的副本選址策略的實現是在這個方向上的第一次努力。實現這個策略的短時間目標是在生產系統中進行驗證,掌握更多行爲並創建一個基礎來測試和研究更加複雜的策略。
HDFS運行在一系列的集羣主機上,這些主機一般分佈在各個機架上。跨機架上的兩個不一樣主機間信息交換須要通過交換機。在大多數狀況下,同一機架中的計算機之間的網絡帶寬大於不一樣機架中的計算機之間的網絡帶寬。
Namenode經過Hadoop Rack Awareness 過程來決定每一個Datanode隸屬於哪一個機架id。一個簡單可是非最佳的策略是將副本放在不一樣機架上。這樣,當一整個機架出現故障時可以防止數據丟失,而且讀取數據能使用到不一樣機架上的帶寬。可是,這種策略增長了寫操做代價,由於須要傳輸塊到不一樣機架上。
當副本數爲3時,HDFS放置策略一般是將一個副本放在本機架的一個節點上,將另外一個副本放在本機架的另外一個節點,最後一個副本放在不一樣機架的不一樣節點上。該策略能夠減小機架之間寫入流量,從而提升寫入性能。機架出現故障的機率要比機器出現故障的機率低,這個策略不會影響數據可靠性和可用性的保證。但這種策略會下降數據讀取時的網絡帶寬,由於數據只放置在兩個機架上而不是三個。這種策略下,文件的副本不是均勻的分佈在各個機架上。三分一個的副本放置在一個節點上,三分之二的副本放置在一個機架上,而另外三分之一均勻分佈在剩餘的機架上。這個策略提升了寫性能而不影響數據可靠性和讀性能。
當前,這裏介紹的默認副本放置策略是一項正在進行的工做。
爲了下降帶寬消耗以及讀取延時,HDFS嘗試讓須要讀取的副本跟讀取者更近。若是存在一個副本在客戶端節點所在的同個機架上,那麼這個副本是知足讀取需求的首選。若是HDFS集羣橫跨多個數據中心,那麼在本地數據中心的副本將是優先於其餘遠程副本。
Namenode剛啓動時會進入一個特殊階段,咱們稱這個階段爲安全模式。當Namenode處於安全模式時,不會發生數據塊的複製。Namenode接收來自Datanode的心跳以及塊報告信息。塊報告包含Datanode持有的一些列數據塊。每一個塊都指定最小副本數。當一個數據塊被NameNode檢查確保它知足最小副本時數,它被認爲是安全的。數據被Namenode檢入,當檢入達到一個百分比(該百分比可配置)時,Namenode退出安全模式。而後Namenode會確認那些副本數小於指定數量的數據塊列表,而且複製這些塊到其餘Datanode上。
HDFS命名空間保存在Namenode上。NmaeNode使用一個稱之爲EditLog的事務日誌持續地記錄發生在文件系統元數據的每個改變。例如,在HDFS中建立一個文件,Namenode將插入一條記錄到EditLog中。一樣,修改文件的複製因子也會致使一條新的記錄插入EditLog中。Namenode使用本地操做系統文件來保存EditLog。整個文件系統命名空間(包括塊到文件的映射以及文件系統屬性)存儲在一個稱爲FsImage的文件中。FsImage一樣存儲在Namenode的本地文件系統中。
Namenode將整個文件系統的命名空間以及塊映射信息保存在內存中。當Namenode啓動時,或者可配置閾值的檢查點被觸發時,Namenode便從磁盤中讀取FsImage和EditLog,將EditLog中的事務應用到表示FsImage的內存中,而後將最新的FsImage內存刷新到磁盤上。而後能夠截斷舊的EditLog,由於新版的EditLog已經持久化到FsImage中。以上整個過程稱爲檢查點(checkpoint)。檢查點的目的是經過獲取文件系統元數據的快照並將其保存到FsImage來確保HDFS具備文件系統元數據的一致視圖。即便讀取FsImage很高效,直接向FsImage增長編輯並不高效。所以針對每次編輯,咱們會放在EditLog中而不是直接修改FsImage。檢查點期間,EditLog的變動信息會應用到FsImage上。能夠以秒爲單位的給定時間間隔(dfs.namenode.checkpoint.period)觸發檢查點,或者在累積給定數量的文件系統事務(dfs.namenode.checkpoint.txns)以後觸發檢查點。當二者均被設置,則哪一個先生效就直接觸發檢查點。
Datanode將HDFS數據保存在本地文件系統的文件中。Datanode對HDFS文件沒有意識,它只是保存HDFS數據的每一個塊,並保存在本地文件系統中的各個文件中。Datanode不會在相同目錄下建立全部文件,而是每一個目錄中有一個最佳文件數,並適當建立子目錄。將全部文件放在同一個目錄下不太明智,由於本地文件系統或許不能有效支持在一個目錄下面存放海量文件。當一個Datanode啓動時,它將掃描本地文件系統,生成全部HDFS數據塊的列表(這些數據塊對應每個本地文件),併發送報告給Namenode。這個報告咱們稱之爲塊報告。
全部HDFS協議均位於TCP/IP之上。一個客戶端創建一個鏈接到Namenode機器上的TCP端口(端口可配置)上。它使用客戶端協議與NameNode通信。Datanode使用Datanode協議與Namenode進行通信。一個遠程過程調用(RPC)封裝了客戶端協議以及Datanode協議。按照設計,NameNode永遠不會啓動任何RPC。 相反,它只響應DataNodes或客戶端發出的RPC請求。
HDFS的主要目標是即便在出現故障時也能可靠地存儲數據。三種常見的故障有:Namanode故障、Datanode故障以及網絡分裂?
每一個Datanode會按期地發送心跳信息給你Namenode。網絡分裂會致使部分Datanode失去與Namenode的聯繫。Namenode經過收不到Datanode的心跳信息來收集這個失聯信息。Namenode標記近期沒有心跳信息的Datanode,並終止對這些Datanode的IO請求。在已經死亡的DataNode註冊的任何數據在HDFS將不能再有效。Datanode故障會致使一些塊的複製因子低於它們的指定值。NameNode時常地跟蹤數據塊是否須要被複制並在必要的時候啓動複製。多個緣由會致使從新複製的操做,例如:Datanode不可用,副本損壞,Datanode磁盤損壞,或者文件的複製因子增大。
將DatNode標記爲死亡的超時時間適當地加長(默認超過10分鐘)是爲了不DataNode狀態改變引發的複製風暴。針對性能敏感的狀況,用戶能夠經過配置來設置更短的時間間隔來標記DataNode爲失效,儘可能避免失效的節點還繼續參與讀寫操做。
HDFS架構兼容數據再平衡方案。當一個Datanode上的剩餘空間降到必定閾值時,方案應該自動將該Datanode上的數據遷移到其餘Datanode上。對於一些特定文件的突發需求,方案應動態地建立額外的副本並從新平衡集羣中的其餘數據。這種方案暫時還未實現。
從DataNode獲取的數據塊可能已損壞。發生損壞的緣由多是存儲設備的故障、網絡故障或者缺陷軟件。HDFS客戶端軟件對HDFS文件的內容進行校驗和檢查。當客戶端建立一個HDFS文件,它會計算文件的每個數據塊的校驗和,並將這些校驗和儲存在HDFS命名空間中一個單獨的隱藏的文件當中。當客戶端從DataNode得到數據時會對對其進行校驗和,而且將之與儲存在相關校驗和文件中的校驗和進行匹配。若是沒有,客戶端會選擇從另外一個擁有該數據塊副本的DataNode上恢復數據。
FsImage和EditLog是HDFS的核心數據架構。這些文件的故障會致使HDFS實例沒法工做。由於這個緣由,HDFS能夠被配置成支持多份FsImage和EditLog備份。任何對FsImage和EditLog的更新,都會致使其餘全部FsImage和EditLog的同步更新。同步更新多份FsImge和EditLog下降NameNode能支持的每秒更新命名空間事務的頻率。然而,頻率的下降是能夠被接受,儘管HDFS應用本質上是對數據敏感,但不是對元數據敏感。當一個NameNode從新啓動,他會選擇最新的FsImage和EditLog來使用。另外一個增長容錯性已達到高可用性的選項是使用多個Namenodes,這個選項的具體實現能夠爲:文件系統的共享存儲、分佈式的編輯日誌(稱爲Journal)。後面會介紹使用方法。
快照支持在特定的時間(瞬間)保存數據的副本。咱們使用的快照特徵多是將損壞的HDFS實例回退到先前一個正常版本。
HDFS被設計成支持很是大的文件。與HDFS兼容的應用程序是處理大型數據集的應用程序。這些程序一次寫入數據屢次讀取,而且這些讀操做知足流式的速度。HDFS支持一次寫入屢次讀取的文件語義。HDFS中,一個典型的塊大小是128兆。所以,一個HDFS文件會被切割成128M大小的塊,若是能夠的話,每個大塊都會分屬於一個不一樣的DatNode。
當客戶端按照3個副本數來寫數據到HDFS文件中,Namenode使用副本目標選擇算法來獲取Datanode列表。這個列表包含塊副本將落地的Datanode。而後客戶端將數據寫入第一個Datanode。第一個Datanode開始分部分接收數據,將每一個部分寫入其本地存儲,並將該部分傳輸到列表中的第二個Datanode。第二個Datanode開始接收數據塊的每一個部分並寫入本地存儲而後傳輸到第三個Datanode。最後,第三個Datanode將數據寫入本地存儲。所以,一個Dataode可以從上一個節點接收數據據並在同一時間將數據轉發給下一個節點。所以,數據在管道中從一個DataNode傳輸到下一個(複製流水線)。
應用程序能夠經過多種方式來訪問HDFS。HDFS自己提供FileSystem Java API讓應用程序來訪問,這個Java Api的C語言封裝版本以及REST API一樣能夠供用戶使用。另外,一個HTTP瀏覽器也能夠訪問HDFS實例中的文件。使用MFS gateway,HDFS能被安裝做爲本地文件系統的一部分。
HDFS提供一個稱爲FS Shell的命令行接口,方便用戶與HDFS中的數據進行交互。這寫命令集合的語法跟其餘咱們熟悉的命令十分類似(例如bash,csh)。下面是一些動做/命令對的示例:
動做 | 命令 |
---|---|
建立目錄 | bin/hadoop dfs -mkdir /foodir |
刪除目錄 | bin/hadoop fs -rm -R /foodir |
查看文件內容 | bin/hadoop dfs -cat /foodir/myfile.txt |
DFSAdmin命令集是用來管理HDFS集羣。只有HDFS管理者才能使用這些命令。下面是一些動做/命令對的示例:
動做 | 命令 |
---|---|
Put the cluster in Safemode | bin/hdfs dfsadmin -safemode enter |
Generate a list of DataNodes | bin/hdfs dfsadmin -report |
Recommission or decommission DataNode(s) | bin/hdfs dfsadmin -refreshNode |
A typical HDFS install configures a web server to expose the HDFS namespace through a configurable TCP port. This allows a user to navigate the HDFS namespace and view the contents of its files using a web browser.
一般安裝HDFS時會配置一個web服務,經過一個配置好的TCP端口來暴露HDFS命名空間。它容許用戶看到HDFS命名空間,並能使用web瀏覽器來查看文件內容。
若是垃圾配置可用,使用HDFS SHELL刪除的文件不會馬上從HDFS刪除,而是被移動到垃圾目錄(每一個用戶都有本身的垃圾目錄:/user//.Trash),文件只要在垃圾目錄中,能夠隨時進行恢復。
大部分剛刪除的文件都被移動到垃圾目錄中(/user//.Trash/Current),而且在一個可配置的間隔時間內,HDFS爲當前垃圾目錄中的文件建立檢查點(under /user//.Trash/),同時刪除那些過時的檢查點。垃圾檢查點信息請點擊expunge command of FS shell
當回收站中的文件過時後,Namenode會從HDFS命名空間中刪除該文件。文件的刪除會致使跟該文件相關聯的塊被釋放。須要說明的是文件被用戶刪除的時間和對應的釋放空間的時間之間有一個明顯的時間延遲。
下面的例子將展現如何經過FS SHELL將文件從HDFS中刪除。咱們在要刪除的目錄中建立test1和test2兩個文件
$ hadoop fs -mkdir -p delete/test1
$ hadoop fs -mkdir -p delete/test2
$ hadoop fs -ls delete/
Found 2 items
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 delete/test1
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:40 delete/test2
複製代碼
咱們將刪除test1文件,下面的日誌顯示文件被移動到垃圾目錄中
$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:8020/user/hadoop/delete/test1 to trash at: hdfs://localhost:8020/user/hadoop/.Trash/Current
複製代碼
如今我來執行將文件刪除跳過垃圾目錄選項(skipTrash),文件則不會轉移到垃圾目錄。文件將徹底從HDFS中移除。
$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2
複製代碼
如今在垃圾目錄中,咱們只能看到test1文件
$ hadoop fs -ls .Trash/Current/user/hadoop/delete/
Found 1 items\
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 .Trash/Current/user/hadoop/delete/test1
複製代碼
也就是test1進入垃圾目錄,而test2被永久刪除。
當文件的複製因子減少時,NameNode將在能夠刪除的副本中選中多餘的副本。在下一個心跳通信中將該信息傳輸給DataNode。而後DataNode移除對應的數據塊而且釋放對應的空間。再重申一遍,在完成複製因子的設置和集羣中出現新的空間之間有個時間延遲。
Hadoop Java API HDFS源碼: hadoop.apache.org/version_con…