1.HDFS體系結構 java
1.1介紹 node
1.2假設和目標 web
1.4 文件系統命名空間 shell
1.5 數據複製 數據庫
1.5.1 Replica Placement: The First Baby Seteps apache
1.5.2 副本選擇 api
1.5.3 安全模式 瀏覽器
1.8.1 Data Disk Failure, Heartbeats and Re-Replication
HDFS是分佈式文件系統,運行在商用的硬件環境上。和其餘的分佈式文件系統類似。可是也有不一樣,HDFS是高度容錯的而且設計用來部署在低成本的硬件上。HDFS提供高吞吐量,比較適合大數據的應用。HDFS釋放POSIX來啓動流方式的訪問文件系統數據。HDFS原來是Apache Nutch網頁搜索引擎的底層服務。HDFS是Apache Hadoop Core項目的一部分。
略
HDFS有Master Slave體系結構。HDFS集羣包含一個NameNode,master服務管理文件系統命名空間和控制client訪問。另外有一些Datanodes,一般Cluster中一個node有一個datanode。用來管理node的空間。HDFS暴露文件系統命名空間容許用戶數據保存在文件中。在內部,文件會被分爲多個塊而且這些塊被保存在一些datanode上。Namenode執行文件系統命名空間操做,好比打開,關閉,重命名文件和目錄。也決定了datanode 的塊映射。Datanode爲client讀寫請求服務。Datanode也執行block的建立,刪除,根據namenode的指令複製。
Namenode和datanode是軟件的一部分。HDFS使用java開發,任何支持java的設備均可以運行namenode和datanode。部署一般有一個專用的機器用來執行namenode。其餘的設備運行datanode。固然也能夠在一個設備上運行多個datanode,可是通常不多出現。
HDFS支持傳統的分層的文件組織,一個用戶或者應用程序建立目錄,文件存在這些目錄中。文件系統命名空間分層和其餘現有的文件系統相似。能夠建立,刪除文件,移動文件,重命名文件。HDFS支持用戶配額和訪問權限。HDFS不支持硬連接或者軟鏈接。可是HDFS不排除這些功能的實現。
Namenode維護文件系統的命名空間。任何修改文件系統命名空間或者屬性都被記錄在Namenode裏面。一個引用程序能夠指定一個文件多個副本維護在HDFS裏面。這些信息也放在namenode裏面。
HDFS設計用來保存大文件到一個大集羣上。每一個文件都以順序的塊存儲。塊被複制用來容錯。塊的大小和複製參數能夠爲每一個文件配置。文件中的全部的塊大小都是同樣的,while users can start a new block without filling out the last block to the configured block size after the support for variable length block was added to append and hsync.
應用能夠指定文件的副本個數。複製參數能夠在文件建立的時候建立,以後能夠修改。HDFS的文件是write-once(除了append和truncate),而且在任什麼時候間都是嚴格的1個writer。
Namenode決定全部的關於複製的塊。按期會接收一個心跳和一個block report。接受一個心跳錶示datanode還活着,block report表示datanode的全部block。
副本的安置對HDFS的可靠性和性能來講是很重要的。優化副本的安置是HDFS和其餘分佈式文件系統的區別。這個特性須要有不少的經驗和調整。目的是機架級別的安置策略,用來提升數據可靠性,可用性和網絡帶寬利用。
對於很大的HDFS集羣來講,一般會傳播到不少機架。不通機架間的node交互須要路過交換機。在不少狀況下同一個機架下的網絡帶寬比不通機架下的設備帶寬搞。
Namenode爲每一個datanode決定rackid,經過Hadoop Rack Awareness來識別。一個最簡單的策略是把副本放到不通的機架下面。這樣若是整個機架錯誤了容許使用其餘的機架下的數據。這個策略均勻的把副本分佈到集羣,能夠很簡單的讓它在出現錯誤的時候來均衡。可是這個策略增長了寫入的開銷,由於要寫入到多個機架下。
對於最一般的例子,複製參數是3,HDFS放置策略是若是writer在本地,那麼放在本地也就是寫入的那個datanode,不然隨機隨機選擇一個datanode,第二個放在一個不通的機架下的datanode上。第三個放在相同的機架的不通datanode下。這個策略減少了機架間的傳輸,提升了寫入性能。機架出現故障的機率遠小於一個node出現錯誤的機率,這個策略不影響可靠性和可用性的保證。可是減小了網絡帶寬的使用,由於一個block只在2個機架中,而不是3個機架。可是這個策略不能讓數據均勻的分佈。1/3的副本在一個node中,2/3的副本在一個機架下,其餘剩下的均勻的分佈在剩下的機架下。這個策略提升了寫入性能並無和可靠性和讀性能衝突。
若是副本參數大於3,那麼第4個副本或者以後的副本是隨機存放的,可是每一個機架存放副本的個數有個上限,(replicas - 1) / racks + 2。
由於namenode不容許datanode擁有同一個block的多個副本,副本的最大個數,就是datanode 的個數。
Storage Types and Storage Policies支持了以後,namenode除了Rack awareness以外,還考慮了這個策略。Namenode選擇node先基於rack awareness,而後檢查候選node的存儲需求。若是候選node沒有storage type,namenode會查看其它node。若是在第一個path的node不夠,那麼namenode在第二個path查找storage path。
爲了最小化帶寬和讀延遲,HDFS會嘗試從最近的一個副本上讀取。若是在同一個機架上面有一個可讀副本,這個副本是被讀取的首選。若是HDFS集羣跨了多個數據中心,那麼本地的數據中心會被首選。
在startup的時候,namenode會進入特別的狀態叫作safemode。在safemode下,數據塊的複製是不會發生的。Namenode從datanode上接受到心跳和blockreport。Blockreport包含了datanode擁有的全部block。每一個block有個副本的最小值。一個block若是在namenode中被檢查完後,那麼就認爲是安全的。若是安全率到達某個值,那麼namenode就退出安全模式。若是發現有一些數據塊的副本不夠,那麼就會建立這些數據庫的副本。
HDFS的命名空間保存在namenode上。Namenode使用事務日誌叫editlog來保存記錄的修改。好比建立一個新的文件,namenode就會插入一條記錄到editlog。一樣的修改複製參數也會在editlog上建立一條機濾。Namenode在系統的文件系統上保存editlog。整個文件系統的命名空間,包括block和文件的映射,文件系統的屬性。都被保存在fsimage中。Fsimage也被保存在本地文件系統上。
Namenode在內存中,保存了整個文件系統命名空間和文件block map的快照。當namenode啓動,或者出發checkpoint,就會從磁盤中把fsimage和editlog讀出來,應用全部editlog上的事務,到內存中的fsimage,而後從新刷新到磁盤中的fsimage。而後能夠截斷,由於已經被應用到磁盤fsimage。這個過程叫checkpoint。目的是保證HDFS有一致性的文件系統元數據。儘管讀取fsimage速度很快,可是增量的直接修改fsimage並不快。咱們不直接修改fsimage,而是保存在editlog中。在checkpoint的時候而後應用的fsimage上。Checkpoint的週期能夠經過參數dfs.namenode.checkpoint.period 指定時間間隔來觸發,也可使用dfs.namenode.checkpoint.txns指定多少個事務以後觸發。若是都設置了,那麼第一個觸發就會checkpoint。
HDFS數據在datanode中以文件的方式被保存在本地文件系統上。Datanode不會在乎HDFS文件。HDFS數據每一個block一個文件保存在本地文件系統上。Datanode不會把全部的文件都放在一個目錄下面。而是使用一個啓發式結構來肯定,每一個目錄的最優文件個數,而且適當的建立子目錄。當datanode啓動,會掃描本地文件系統,生成一個HDFS的列表,而且發送給namenode。這個report叫blockreport。
全部HDFS交互協議都是基於tcp/ip的client建立一個鏈接到namenode機器。使用clientprotocol和namenode交互,datanode使用datanode protocol和namenode交互。Namenode並不開啓任何RPC。只是對datanode 和client的反應。
儘管存在錯誤,HDFS保存數據仍是可靠的。一下是一些namenode錯誤,datanode錯誤和網絡分區。
每一個datanode會發送心跳信息到namenode。網絡分區會致使子網的datanode和namenode 的鏈接中斷。Namenode經過心跳信息來發現。Namenode把沒有收到心跳信息的node標記爲死亡,而且發送新的IO請求到這個node。任何數據在死亡的datanode不在對HDFS可用。Datanode 的死亡會致使一些block的複製參數少於指定的值。Namenode會不間斷的跟蹤這些須要複製的block,而且在有須要的時候啓動複製。須要從新複製的理由可能不少:datanode變的不可用,副本損壞,datanode所在的硬件損壞,或者複製參數增長。
HDFS結構兼容數據再平衡框架。若是一個datanode的空閒超過了閥值,一個框架可能把數據從一個datanode移動到另一個。若是一個特定的文件請求特別高,框架會動態的建立副本而且再平衡數據。數據再平衡目前沒有實現。
一個block的數據出現損壞是頗有可能的。出現損壞,多是磁盤問題,網絡問題或者有bug。HDFS客戶端軟件實現了checksum檢查HDFS文件的內容。當一個客戶端建立了HDFS文件。會爲每一個block計算checksum而且保存在在同一個命名空間下,獨立的隱藏文件下。當client獲取文件內容,須要驗證每一個datanode的checksum和checksum文件中的一致。若是不一致,從副本上獲取。
Fsiamge和editlog是HDFS結構的核心。若是出現損壞,會致使HDFS實例沒法運行。由於這個能夠配置fsimage和editlog多個副本。任何更新fsimage和editlog會同步的更新副本。同步的更新fsiamge和editlog可能會致使性能問題。然而仍是能夠接受的,由於HDFS是數據敏感而不是元數據敏感的。當namenode重啓會選擇最新的fsimage和editlog使用。
另一個選項是使用多namenode啓動HA,或者使用NFS共享存儲,分佈式的editlog。
快照是被支持的。快照的一個用處是修復HDFS。
HDFS被設計用來支持很是大的文件。應用使用HDFS來處理這些文件。這些應用只寫一次可是要讀不少次。HDFS支持write-once-read-many。一般HDFS block大小是128MB。所以HDFS會被切成128MB的塊。
當client寫數據到HDFS,而且複製參數是3,namenode會獲取datanode的一個列表使用複製選擇算法。這些列表包含了datanode 的副本block。Client而後寫入第一個datanode。第一個datanode一部分一部分的接受數據,把每一個部分寫到本地的存儲庫中而且把這部分傳輸到list中的第二個datanode。第二個datanode,同樣接受數據,而後存儲到本地存儲庫,而後傳輸到第三個datanode。第三個datanode,接受數據保存到本地存儲庫。所以數據是以pipeline的方式從一個到另一個。
HDFS能夠以不一樣的方式被訪問。最原始的使用java 的API。也可使用http瀏覽器。HDFS能夠被mount到client本地文件系統。
HDFS容許用戶數據以目錄和文件的方式組織。提供了命令行藉口FSShell可讓用戶和HDFS交互。語法和bash相似。
Action |
Command |
Create a directory named /foodir |
bin/hadoop dfs -mkdir /foodir |
Remove a directory named /foodir |
bin/hadoop fs -rm -R /foodir |
View the contents of a file named /foodir/myfile.txt |
bin/hadoop dfs -cat /foodir/myfile.txt |
DFSAdmin命令主要用來管理HDFS集羣。
Action |
Command |
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 -refreshNodes |
HDFS安裝配置了web服務來暴露HDFS的命名空間。容許經過瀏覽器查看和定位文件。
若是trash配置啓用了,FSShell刪除的文件並不會立刻從HDFS上面刪除。HDFS會把這些移動到trash目錄中(/user/<username>/.Trash)。這樣文件能夠快速的恢復。
最近被刪除的文件會被移動到當前的trash目錄(/user/<username>/.Trash/Current),根據checkpoint的配置,HDFS爲當前的刪除建立checkpoint(/user/<username>/.Trash/<date>),到期後會刪除老的checkpoint。查看 expunge command of FS shell
到期以後,namenode會刪除文件的元數據。刪除後會致使相關的block被回收。例子以下:
建立2個文件
$ 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
刪除一個文件根據提示被移動到了trash目錄
$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:9820/user/hadoop/delete/test1 to trash at: hdfs://localhost:9820/user/hadoop/.Trash/Current
刪除test2,可是跳過trash
$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2
最後只會看到trash中的一個文件
$ 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
當複製數量減小,namenode會選擇多餘的副本進行刪除。在下一次心跳傳輸給datanode,datanode而後刪除響應的塊,釋放空間。經過setReplication API設置到真正釋放空間有延遲。
Hadoop JavaDoc API.
HDFS source code: http://hadoop.apache.org/version_control.html