本文主要參考 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html 主要內容是對該文章的翻譯,部分內容參考其他的網路文章。 1.簡介 hadoop分散式文件系統(HDFS)是一個分散式 ...
本文主要參考 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html
主要內容是對該文章的翻譯,部分內容參考其他的網路文章。
1.簡介
hadoop分散式文件系統(HDFS)是一個分散式文件系統,運行於普通的硬體之上(例如pc或者廉價刀片伺服器).HDFS和現有的分散式文件系統有許多相似之處。然而,不同之處也是很明顯的。
HDFS是高容錯,並用於部署在低成本的硬體之上。HDFS為應用數據提供很高的吞吐,使用有大量數據的應用。
HDFS實現了部分POSIX功能,允許通過流的方式訪問文件系統數據。
2.假設和目標
- 硬體故障
硬體故障比異常更加普遍。一個HDFS實例可能包含了成千上萬的伺服器,每個伺服器存儲了文件系統數據的一部分。由於有大量的組件,而每個組件都有可能出現故障,所以總有一些部件是無法工作的。因此,檢測到故障,並快速且自動恢復這些部件,就是HDFS的核心架構目標。
- 流數據存儲
http://www.cnblogs.com/beanmoon/archive/2012/12/17/2821548.html
POSIX標準有許多的硬體要求,但這些要求並不符合HDFS要求。但POSIX在某些小且關鍵的方面可以用於提升數據吞吐率.
- 大數據集
運行於HDFS之上的應用具有大數據集。HDFS中的一個典型文件的大小介於G~T.因此,HDFS針對大文件進行優化。它應該提供高的總量數據帶寬,並可以在一個集群中擴展到上千的節點。它可以在單一的實例中支持幾千萬的的文件。
- 簡單一致性
HDFS應用需要個一次寫入需多次讀的文件存取模式。一個文件一旦創建,寫入和關閉,就不需要改變,除非為了添加數據或者清空。數據只能添加到尾部,而不是任意點。
這種假設簡化了數據一致性問題,並使得高吞吐量成為可能。一個MR原因或者一個web爬蟲應用特別適合這種模式。
- 傳輸的成本大於計算成本
如果計算能夠離需要的數據近一些,那麼無疑更有效。當需要的數據特別大的時候,這種情況就特別明顯。因為這會最小化網路堵塞,並提升總體的吞吐量。假設:計算靠近數據總是比數據靠近計算來得好。
HDFS提供了一個介面,讓應用的計算更加靠近數據。
- 在各種各樣的硬體和軟體平臺之間遷移
HDFS的設計目的之一就是讓它更方便遷移。
3.名稱節點和數據節點
HDFS是一個主從結構。一個HDFS集群包含了一個名稱節點(namenode),這個節點負責管理文件系統名稱空間,並調控客戶端對文件的訪問。此外,集群還有許多的數據節點(NAMENODE),通常一個節點上一個數據節點,數據節點管理節點上的存儲。
HDFS提供一個系統名稱空間,並允許用戶的數據以文件的方式存儲。在內部,一個文件通常被分割為多個塊(也可能是一個塊,根據文件大小和參數不同而定),這些數據塊被存儲在多個節點上。
名稱節點執行文件系統名稱空間操作,諸如打開,關閉,和重新命名文件和目錄。名稱節點也決定數據塊和數據節點的映射關係。
數據節點負責為客戶端提供讀寫請求,同時也負責塊的創建,刪除,和複製(根據名稱節點的要求)。
名稱節點和數據節點在設計的時候,就被要求是能夠運行在普通的機器上的軟體。這些機器典型地要求運行GNU/LIUX操作系統。
HDFS是使用java語言構建的。任意支持java的機器都可以運行名稱節點和數據節點軟體。使用java這種可移植語言,意味著,HDFS可以被部署在許多機器上。
典型的部署就是,一個專有的機器運行名稱節點。機器中的其它節點運行數據節點軟體。框架並不阻止一臺機器上運行多個數據節點(但一般人不這麼做,一般情況也不這兒做)。
單一名稱節點的存在極大地簡化了系統的框架。名稱節點就是所有HDFS元數據的一個仲裁人和倉庫。系統這樣設計,並讓用戶的數據永遠不會通過名稱節點(非常重要)。
4.文件系統命名空間
HDFS支持傳統文件組織。用戶或者應用可以創建目錄,併在目錄中存儲文件。文件系統名稱空間層次類似於絕大部分現有的文件系統。
就是說HDFS也可以創建和移除文件,在目錄之間移動文件,或者重新命名一個文件。HDFS支持用戶配額和存取許可權(模仿傳統文件系統)。但HDFS並不支持軟硬鏈接,雖然HDFS的框架並不阻礙這些特性的實現。
名稱節點維護系統名稱空間。對文件系統名稱空間或者屬性的任意修改都會被名稱節點記錄。一個應用可以設定HDFS複製文件的份數。
文件拷貝數被稱為文件的複製因數,這些信息存儲在名稱節點。
5.數據複製
- 複製定位:嬰兒的第一步
HDFS設計的目的就是為了在一個大型集群中可靠地存儲非常大的文件。HDFS把每個文件存儲為一系列的數據塊。通過複製文件的數據塊達到容錯目的。數據塊大小和複製因數可以按照具體文件來配置。
除了最後一塊,其它數據塊大小一致。當要添加數據的時候, 用戶可以不填滿最後一塊,而是直接開新快來存儲數據。
一個應用可以文件的複製個數。複製因數可以在文件創建的設定,之後也可以修改。HDFS中的文件只寫一次(除了附加和清空),在任意時候,一個文件只有一個寫入程式。
名稱節點決定文件的各種操作,除了複製因數。名稱節點定期從數據節點接受心跳和塊報告。能夠收到心跳,意味著,數據節點工作正常。
一個塊報告包含節點上所有塊的列表(清單)。
- 複製的選擇
為了最小化全局帶塊的消耗,並減少讀取延遲,HDFS力圖從接近讀取程式的複製中滿足一個讀請求。如果在讀取節點的同一個架子上存儲複製信息,那麼複製信息就是一個更好的選擇。如果HDFS
集群擴展為多個數據中心,那麼本地數據中心的選擇比遠程中心的更好。
譯註:這個告訴我們,如何搭建機架和數據中心,是很重要的,它會影響到數據讀取的效率。
- 安全模式
在啟動的時候,名稱節點會進入一個特別的狀態,這個狀態稱為安全模式。安全模式下,並不進行數據複製。
名稱節點從數據節點接受心跳和數據塊報告。數據塊報告包含了特定節點上數據塊的清單。每個塊有一個特定最小複製數。只有一個塊的最小複製數滿足名稱節點檢查要求,這個塊才能認為是安全複製的。
經過名稱節點中安全複製數據塊的檢查(檢查的比例可以配置,檢查的過程大約要30秒左右)後,名稱節點退出安全模式。然後,名稱節點會確定那些沒有滿足安全複製的數據塊清單,併為這些塊做必要的安裝複製。
6.文件系統元數據持久性
hdfs名稱空間由名稱節點存儲。名稱節點使用編輯日誌(editlog)來記錄系統元數據的每個變化(這個日誌是一個事務日誌)。例如,在HDFS創建一個新文件,那麼名稱節點會在編輯日誌中插入一條針對新文件的記錄。
類似地,如果修改一個文件的複製因數,名稱節點也會插入一條編輯日誌。名稱節點使用本地操作系統的文件系統中的一個文件來存儲編輯日誌。
整個文件系統名稱空間,包括文件塊映射信息和文件系統屬性,存儲在文件FsImage中。FsImage存儲方式同Editlog.
名稱節點會再記憶體中存儲整個文件系統名稱空間和文件塊映射信息。當名稱節點啟動的時候,或者可配瓶頸觸發一個檢查點的時候,名稱節點從FsImage,EditLog讀取信息。
編輯日誌的所有事務會應用到記憶體中的FSIMAGE中,然後記憶體中的fsimage會寫到磁碟中的一個新的fsImage文件中。名稱節點然後就可以清楚老的編輯日誌,因為老日誌的所有事務已經應用到持久的FSIMAGE中。
這種操作稱為一個檢查點。檢查點的目的就是為了確認文件系統元數據有一個一致的視圖,檢查的途徑就是從文件系統元數據獲得一個快照,並把它們存儲在FSIMAGE。
雖然讀FSIMAGE是比較高效,但增量編輯FSIMAGE並不高效。所以,名稱節點不是逐次編輯FSIMAGE,而是把這些編輯信息記錄在編輯日誌中(然後通過檢查點更新).
檢查點可以按照特定的間隔觸發(通過dfs.namenode.checkpoint.period來控制),間隔單位是秒,或者一個給定的累積文件系統事務數(dfs.namenode.checkpoint.txns).
如果兩個屬相都有設定,那麼任何之後,只有滿足其中之一,就會觸發檢查點操作。
數據節點使用本地文件系統來存儲HDFS數據。數據節點並不關心HDFS文件。它們使用本地文件系統的單獨文件來存儲HDFS數據的每個數據塊。
名稱節點不會在一個節點下創建所有文件。它們使用探索方法來確定每個目錄的最佳文件數,併在必要的時候,創建子目錄。
在同個目錄創建所有的本地文件並不是最好的選擇,因為本地文件系統可能無法有效地在單個目錄中支持巨量的文件(譯註:在有巨多的文件的目錄中ls就知道了,linux這個方面好像不如windows 的dir來得明智)。
當一個數據節點啟動的時候,它會掃描本地文件系統,並生成HDFS數據塊和本地文件的映射清單,並把這個報告發送給名稱節點。這個報告就是塊報告(blockreport)
7.通信協議
所有的HDFS通信協議基於TCP/IP。一個客戶端通過名稱節點的一個可配TCP埠來建立連接。客戶端和名稱節點談論客戶端協議。數據節點使用數據節點協議和名稱節點談論。
一個遠程過程調用(rpc)通過抽象的方式包裝了客戶端協議和數據節點協議。
按照設計要求,名稱節點用不初始化任何的PRC(不主動發起任何rpc),反之,名稱節點只會應答數據節點和客戶端的rpc請求。
8.強壯性
- 數據磁碟故障,心跳和重新同步
每個數據節點都會定期發送心跳信息給名稱節點。網路斷開會導致一部分的數據節點失去和名稱節點的聯繫。名稱節點通過心跳信息的缺失來偵測這種情況。
名稱節點把最近沒有心跳信息的數據節點的狀態標記為死亡(dead),並不再提交新的io請求給這些死亡節點。於是死亡幾點上的數據對於HDFS而言不再可用。
數據節點的死亡可能會導致部分數據塊的複製因數低於特定的值。名稱節點不斷追蹤哪些數據塊需要被覆制,併在必要的時候啟動複製。
重新複製可能是許多原因導致的:數據節點不可用,某個複製壞掉了,數據節點上的磁碟發生故障,或者文件的複製因數變大了。
用於標記死亡狀態的失聯間隔目前設置得很保守(預設超過10分鐘) ,目的是避免不穩定的數據節點導致的複製風暴。
用戶可以設置更短一些的間隔(這種間隔內沒有聯繫),把數據節點標記為陳舊(stale),以避免陳舊的節點被用作負載(進行讀寫操作,換言之,這些節點不再使用,但也不容易引起複制風暴)
- 集群重平衡(均衡)
HDFS架構可以滿足數據重平衡的方案。一個方案可能自動把數據從一個節點移動到其它節點,如果特定節點的剩餘空間低於閥值。
在一種對特定文件有大量需求的情況下,方案可能會動態創建額外的複製,並重新平衡集群中的數據。這種類型的數據重平衡方案並不是隱式的(就是要手動發起)。
- 數據完整
有可能從節點傳輸來的數據是損壞的。原因可能是存儲設備,網路故障,或者有bug的軟體。HDFS客戶端軟體會進行HDFS文件的檢驗(使用checksum方式)。
當一個客戶端創建一個HDFS文件,它會計算文件中每個塊的checksum,併在單獨隱藏文件中保存這些checksum(這個文件和數據在同個hdfs名稱空間)。
當一個客戶取數據的時候,會同時計算checksum,並看看是否和以前存的checcksum值一致。如果不是,那麼,客戶端可能會從其它節點使用複製塊來替代。
- 元數據磁碟故障
FSIMAGE和EDITLOG是HDFS的核心數據結構。如果它們有問題,那麼整個集群就癱瘓了。因此,如果有必要,可以在名稱節點上存儲多個拷貝(這些事可配的)。
只要更新兩個文件中的一個,那麼兩個文件都會被同步更新。由於需要同步多個拷貝,這樣就可能降低名稱節點的事務率(單位之間執行的事務個數)。然而,這種降低是可以接受的,因為即使HDFS的應用對數據非常依賴,但它們對元數據不是那麼依賴(不是時時刻刻需要,偶爾訪問即可)。當一個名稱節點重啟的時候,它會使用最近一致的FSIMAGE和editlog。
另外一個提高容錯彈性的選擇是啟用多名稱節點的高可靠性。多個節點之間可以使用基於NFS的共性存儲,或者使用一個分散式編輯日誌(稱為日誌? journal)。
journal是一個推薦的方案。
- 快照
Snapshots support storing a copy of data at a particular instant of time. One usage of the snapshot feature may be to roll back a corrupted HDFS instance to a previously known good point in time.
快照能夠保存特定瞬間的數據拷貝。一旦使用快照,就可以把一個破損的HDFS實力回滾到特定的時間點(譯註:存儲要求太高了。而且照相一次,要耗費多少時間了?)。
8.數據組織
- 數據塊
hdfs設計用於支持非常大的文件。需要用HDFS的用於都是需要處理大數據集的。這些應用寫一次數據,但會讀取一次或者多次,並且要求這些讀能否以流速度的方式進行。HDFS一次寫多次讀的文件操作。一個典型的HDFS塊大小是128m。因此,每個HDFS文件按照128m的方式進行分塊,如果有可能的話,每個塊都應該在不同的節點上。
(所以,需要根據應用的情況,分析下應該使用到多少節點,部署事先應該有計算過)
- 緩存(階段-staging)
一個客戶端關於創建文件的請求是不會立即達到名稱節點的。事實上,開始的時候,HDFS客戶端會在本地緩衝中緩存文件數據。應用的寫被透明引導到本地緩衝。
當本地文件所累積的數據達到一定量的時候,客戶端會聯繫名稱節點(譯註:緩存以提高效率,是很平常很正確的選擇)。名稱節點隨後把文件名稱插入到文件系統結構中,併為文件分配一個塊。
然後,名稱節點把數據節點和目標數據塊的信息返回給客戶端的請求。再然後,客戶端把緩衝中的數據發送給指定的數據節點。當文件關閉的時候,本地緩衝中尚未發送的數據會被傳輸給數據節點,客戶端然後告訴名稱節點,文件被關閉了。
在這個時刻,名稱節點提交創建事務,並把有關數據存儲在持久存儲中。如果數據節點在文件關閉前死亡,那麼文件就會丟失。
以上的方案是在謹慎考慮後,被基於HDFS的應用採用的。這些原因需要流式寫文件。如果一個客戶端直接寫遠程文件,但又沒有使用客戶端的緩衝,那麼網速和網路堵塞會對系統的吞吐量造成客觀的影響。
這個方案沒有先例。
更早的文件系統等,例如afs(譯註:這文件系統和nfs一樣都是分散式文件系統,但前者讀起來方便,寫比較麻煩,和hdfs有點像),使用客戶端緩衝來提升性能。
POSIX中部分要求已經被實現,以期獲得更好的文件上傳性能。
- 複製管道
當一個客戶端寫數據到HDFS文件中的時候,數據是先寫入到本地緩衝。假定這個HDFS文件的複製因數是3.
客戶端本地緩衝中的數據累積到一定程度後,從名稱節點獲取一個數據節點清單。然後,客戶端開始把這些數據傳輸給數據節點。
第一個數據節點並非一次接受一個完整的緩衝數據,而是分開來一次次做的。首先接受一小部分,然後寫入到本地倉庫,然後把數據傳輸給清單中的第二個數據節點。第二數據節點和第一個節點一樣操作,然後數據發送到第三個節點。
就這樣,數據就是從一個節點傳輸到另外一個節點,好像管道傳輸一樣。
9.存取
HDFS可以使用應用,以多個途徑訪問。
最原始的方式是文件系統JAVA API。 還有包裝java api的c語言api,以及rest api(譯註:rest看起來比較複雜,及時通過http來訪問)。
此外,一個http瀏覽器也可以用戶瀏覽HDFS實例中的文件。通過使用NFS網關,HDFS可以掛載到本地文件系統。
- FS SHELL
HDFS允許用戶數據按照目錄和文件的方式組織。HDFS提供了一個命令行界面,這個界面稱為FS SHELL。
FS SHELL提供的語法和其它shell的語法類似(bash,csh),用戶很容易上手。
如果應用需要使用腳本,可以通過fs shell來訪問hdfs中的數據。
- dfsadmin
DFSADMIN 命令集用於管理hdfs集群。例如:
bin/hdfs dfsadmin -safemode enter --把集群置為安全模式
bin/hdfs dfsadmin -report -- 生成一個報告
bin/hdfs dfsadmin -refreshNodes --刷新數據節點
- 瀏覽器界面
一個典型的Hdfs安裝會配置一個web伺服器,伺服器會把hdfs的名稱空間通過特定埠(可配)發佈。這樣用戶就可以使用web瀏覽器來查看HDFS名稱空間,並查看文件的內容。
10.空間回收(分配)
- 文件刪除和取消刪除
如果有配置垃圾箱(譯註:core-site.xml中 fs.trash.interval 非0就是開啟),那麼通過FS SHELL移除的文件不會立刻從HDFS移除。hdfs會把這些文件移動到一個垃圾目錄(每個用戶都有自己的垃圾目錄/user/<username>/.Trash).
如果文件還在垃圾箱中,就可以立刻恢復。
最近刪除的文件會被移動到當前垃圾目錄(/user/<username>/.Trash/Current),在一個可配置的間隔後,HDFS會創建檢查點(/user/<username>/.Trash/<date>),並刪除過期的檢查點。 詳細信息可以參閱 expunge command of FS shell.
當垃圾過期後,名稱節點從名稱空間刪除指定文件。相關的數據塊被釋放。註意,因為這個機制,用戶刪除一個文件後,hdfs可能需要過一段時間才會釋放空間。
如何繞過垃圾箱機制,下麵是一個例子:
hadoop fs -rm -r -skipTrash delete/test2
- 降低複製因數
When the replication factor of a file is reduced, the NameNode selects excess replicas that can be deleted. The next Heartbeat transfers this information to the DataNode. The DataNode then removes the corresponding blocks and the corresponding free space appears in the cluster. Once again, there might be a time delay between the completion of the setReplication API call and the appearance of free space in the cluster.
當降低複製因數後,名稱節點會把多餘的複製塊刪除掉。下一個心跳時候,會把這個信息傳遞給數據節點。數據節點會移除對應的塊。隨後集群中會出現對應的可用空間。
再一次,調低複製因數到看到集群可用空間增加(通常)之間,會存在一定延遲。
彙總:
本文簡要描述了hdfs的架構,總體上還是很清楚的,原文還帶有圖,不過就個人來看,覺得這些圖不是很容易理解,還不如文字形象。
文章覆蓋了hdfs架構的各個核心方面,包括原理,性能,高可靠等等。