『壹』 HDFS架構
HDFS中的文件是以數據塊(Block)的形式存儲的,默認最基本的存儲單位是128 MB(Hadoop 1.x為64 MB)的數據塊。也就是說,存儲在HDFS中的文件都會被分割成128 MB一塊的數據塊進行存儲,如果文件本身小於一個數據塊的大小,則按實際大小存儲,並不佔用整個數據塊空間。HDFS的數據塊之所以會設置這么大,其目的是減少定址開銷。數據塊數量越多,定址數據塊所耗的時間就越多。當然也不會設置過大,MapRece中的Map任務通常一次只處理一個塊中的數據,如果任務數太少,作業的運行速度就會比較慢。HDFS的每一個數據塊默認都有三個副本,分別存儲在不同的DataNode上,以實現容錯功能。因此,若數據塊的某個副本丟失並不會影響對數據塊的訪問。數據塊大小和副本數量可在配置文件中更改
NameNode是HDFS中存儲元數據(文件名稱、大小和位置等信息)的地方,它將所有文件和文件夾的元數據保存在一個文件系統目錄樹中,任何元數據信息的改變,NameNode都會記錄。HDFS中的每個文件都被拆分為多個數據塊存放,這種文件與數據塊的對應關系也存儲在文件系統目錄樹中,由NameNode維護。NameNode還存儲數據塊到DataNode的映射信息,這種映射信息包括:數據塊存放在哪些DataNode上、每個DataNode上保存了哪些數據塊。NameNode也會周期性地接收來自集群中DataNode的「心跳」和「塊報告」。通過「心跳」與DataNode保持通信,監控DataNode的狀態(活著還是宕機),若長時間接收不到「心跳」信息,NameNode會認為DataNode已經宕機,從而做出相應的調整策略。「塊報告」包含了DataNode上所有數據塊的列表信息。
DataNode是HDFS中真正存儲數據的地方。客戶端可以向DataNode請求寫入或讀取數據塊,DataNode還在來自NameNode的指令下執行塊的創建、刪除和復制,並且周期性地向NameNode匯報數據塊信息。
NodeSecondaryNameNode用於幫助NameNode管理元數據,從而使NameNode能夠快速、高效地工作。它並不是第二個NameNode,僅是NameNode的一個輔助工具。HDFS的元數據信息主要存儲於兩個文件中:fsimage和edits。fsimage是文件系統映射文件,主要存儲文件元數據信息,其中包含文件系統所有目錄、文件信息以及數據塊的索引;edits是HDFS操作日誌文件,HDFS對文件系統的修改日誌會存儲到該文件中。當NameNode啟動時,會從文件fsimage中讀取HDFS的狀態,也會對文件fsimage和edits進行合並,得到完整的元數據信息,隨後會將新HDFS狀態寫入fsimage。但是在繁忙的集群中,edits文件會隨著時間的推移變得非常大,這就導致NameNode下一次啟動的時間會非常長。為了解決這個問題,則產生了SecondaryNameNode,SecondaryNameNode會定期協助NameNode合並fsimage和edits文件,並使edits文件的大小保持在一定的限制內。SecondaryNameNode通常與NameNode在不同的計算機上運行,因為它的內存需求與NameNode相同,這樣可以減輕NameNode所在計算機的壓力。
『貳』 hdfs的啟動流程
整理HDFS整個啟動的詳細過程
Namenode保存文件系統元數據鏡像,namenode在內存及磁碟(fsimage和editslog)上分別存在一份元數據鏡像文件,內存中元數據鏡像保證了hdfs文件系統文件訪問效率,磁碟上的元數據鏡像保證了hdfs文件系統的安全性。
namenode在磁碟上的兩類文件組成:
fsimage文件:保存文件系統至上次checkpoint為止目錄和文件元數據。
edits文件:保存文件系統從上次checkpoint起對hdfs的所有操作記錄日誌信息。
fsimage和editlog文件可以在本地文件系統看到
首次安裝格式化(format)主要作用是在本地文件系統生成fsimage文件。
1、首此啟動hdfs過程:
啟動namenode:
讀取fsimage生成內存中元數據鏡像。
啟動datanode:
向namenode注冊;
向namenode發送blockreport。
啟動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在edits文件中。
2、之後啟動HDFS文件系統過程:
啟動namenode:
讀取fsimage元數據鏡像文件,載入到內存中。
讀取editlog日誌文件,載入到內存中,使當前內存中元數據信息與上次關閉系統時保持一致。然後在磁碟上生成一份同內存中元數據鏡像相同的fsimage文件,同時生成一個新的null的editlog文件用於記錄以後的hdfs文件系統的更改。
啟動datanode:
向namenode注冊;
向namenode發送blockreport。
啟動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在editlog文件中。
3、SecondaryNameNode
輔助namenode,不能代替namenode。
SecondaryNameNode的主要作用是用於合並fsimage和editlog文件。在沒有SecondaryNameNode守護進程的情況下,從namenode啟動開始至namenode關閉期間所有的HDFS更改操作都將記錄到editlog文件,這樣會造成巨大的editlog文件,所帶來的直接危害就是下次啟動namenode過程會非常漫長。
在啟動SecondaryNameNode守護進程後,每當滿足一定的觸發條件(每3600s、文件數量增加100w等),SecondaryNameNode都會拷貝namenode的fsimage和editlog文件到自己的目錄下,首先將fsimage載入到內存中,然後載入editlog文件到內存中合並fsimage和editlog文件為一個新的fsimage文件,然後將新的fsimage文件拷貝回namenode目錄下。並且聲稱新的editlog文件用於記錄DFS的更改。
4、安全模式
在啟動namenode至所有datanode啟動完成前的階段成為安全模式。在安全模式下,client只能讀取部分HDFS文件信息,不允許client對HDFS的任何更改操作,比如創建目錄、上傳文件、刪除文件、重命名文件等。
namenode推出安全模式條件需要滿足以下條件:
datanodes blocks/total blocks >= 99.999% + 30s(緩沖時間) 此時安全模式才會推出
Secondary namenode工作流程:
1)secondary通知namenode切換edits文件
2)secondary通過http請求從namenode獲得fsimage和edits文件
3)secondary將fsimage載入內存,然後開始合並edits
4)secondary將新的fsimage發回給namenode
5)namenode用新的fsimage替換舊的fsimage
『叄』 FSImage 和 EditsLog
HDFS 是一個分布式文件存儲系統,文件分布式存儲在多個 DataNode 節點上。一個文件存儲在哪些 DataNode 節點的哪些位置的元數據信息(metadata)由 NameNode 節點來處理。而隨著存儲文件的增多,NameNode 上存儲的信息也會越來越多。那麼 HDFS 是如何及時更新這些metadata的呢?
完整的 metadata 信息就應該由 FSImage 文件和 edit log 文件組成。fsimage 中存儲的信息就相當於整個 hdfs 在某一時刻的一個快照。
在某一次啟動HDFS時,會從 FSImage 文件中讀取當前 HDFS 文件的 metadata ,之後對 HDFS 的所有操作都會記錄到 edit log 文件中。比如下面這個操作過程:
fsImage 文件和 editsLog 文件是通過 id 來互相關聯的
從上圖可以看到:
但是這里會出現一個問題,一旦重新啟動 HDFS 時,由於需要載入 fsimage,以及所有的 txid 大於 fsimage 的 edit log,當 edit log 文件越來越多、越來越大時,整個重啟過程就會耗時非常之久。
fsimage 和 edit log 合並的過程如下圖所示:
那麼什麼時候進行 checkpoint ,由下面兩個參數來確定:
在HA模式下 checkpoint 過程由StandBy NameNode來進行,Active NameNode將edit log文件會同時寫入多個 JournalNodes 節點的 dfs.journalnode.edits.dir 路徑下,(JournalNodes 的個數為大於1的奇數,當有不超過一半的 JournalNodes 出現故障時,仍然能保證集群的穩定運行)。
StandBy NameNode 會讀取 FSImage 文件中的內容,並且每隔一段時間就會把 Active NameNode 寫入edit log中的記錄讀取出來,這樣 StandBy NameNode 的NameNode進程中一直保持著 hdfs 文件系統的最新狀況的 namespace。當達到 checkpoint 條件的某一個時,就會直接將該信息寫入一個新的 FSImage 文件中,然後通過HTTP傳輸給 Active NameNode 。
如上圖所示,整個同步過程如下:
JournalNode 其實不參與 NameNode 的 metadata 同步之類的操作,它只是個忠實的存儲,存儲來自於NameNode 的操作日誌,Active NameNode 在文件系統被修改時,會向JournalNode寫入修改記錄,而 Standby NameNode 可以方便的讀取到這樣的修改記錄。
『肆』 大數據之HDFS
在現代的企業環境中,單機容量往往無法存儲大量數據,需要跨機器存儲。統一管理分布在集群上的文件系統稱為 分布式文件系統 。
HDFS (Hadoop Distributed File System)是 Hadoop 的核心組件之一, 非常適於存儲大型數據 (比如 TB 和 PB), HDFS 使用多台計算機存儲文件,並且提供統一的訪問介面,像是訪問一個普通文件系統一樣使用分布式文件系統。
HDFS是分布式計算中數據存儲管理的基礎,是基於流數據模式訪問和處理超大文件的需求而開發的,可以運行於廉價的商用伺服器上。它所具有的 高容錯、高可靠性、高可擴展性、高獲得性、高吞吐率 等特徵為海量數據提供了不怕故障的存儲,為超大數據集的應用處理帶來了很多便利。
HDFS 具有以下 優點 :
當然 HDFS 也有它的 劣勢 ,並不適合以下場合:
HDFS 採用Master/Slave的架構來存儲數據,這種架構主要由四個部分組成,分別為HDFS Client、NameNode、DataNode和Secondary NameNode。
Namenode是整個文件系統的管理節點,負責接收用戶的操作請求。它維護著整個文件系統的目錄樹,文件的元數據信息以及文件到塊的對應關系和塊到節點的對應關系。
Namenode保存了兩個核心的數據結構:
在NameNode啟動的時候,先將fsimage中的文件系統元數據信息載入到內存,然後根據edits中的記錄將內存中的元數據同步到最新狀態;所以,這兩個文件一旦損壞或丟失,將導致整個HDFS文件系統不可用。
為了避免edits文件過大, SecondaryNameNode會按照時間閾值或者大小閾值,周期性的將fsimage和edits合並 ,然後將最新的fsimage推送給NameNode。
並非 NameNode 的熱備。當NameNode 掛掉的時候,它並不能馬上替換 NameNode 並提供服務。其主要任務是輔助 NameNode,定期合並 fsimage和fsedits。
Datanode是實際存儲數據塊的地方,負責執行數據塊的讀/寫操作。
一個數據塊在DataNode以文件存儲在磁碟上,包括兩個文件,一個是數據本身,一個是元數據,包括數據塊的長度,塊數據的校驗和,以及時間戳。
文件劃分成塊,默認大小128M,以快為單位,每個塊有多個副本(默認3個)存儲不同的機器上。
Hadoop2.X默認128M, 小於一個塊的文件,並不會占據整個塊的空間 。Block數據塊大小設置較大的原因:
文件上傳 HDFS 的時候,Client 將文件切分成 一個一個的Block,然後進行存儲。
Client 還提供一些命令來管理 HDFS,比如啟動或者關閉HDFS。
Namenode始終在內存中保存metedata,用於處理「讀請求」,到有「寫請求」到來時,namenode會首 先寫editlog到磁碟,即向edits文件中寫日誌,成功返回後,才會修改內存 ,並且向客戶端返回,Hadoop會維護一個fsimage文件,也就是namenode中metedata的鏡像,但是fsimage不會隨時與namenode內存中的metedata保持一致,而是每隔一段時間通過合並edits文件來更新內容。
HDFS HA(High Availability)是為了解決單點故障問題。
HA集群設置兩個名稱節點,「活躍( Active )」和「待命( Standby )」,兩種名稱節點的狀態同步,可以藉助於一個共享存儲系統來實現,一旦活躍名稱節點出現故障,就可以立即切換到待命名稱節點。
為了保證讀寫數據一致性,HDFS集群設計為只能有一個狀態為Active的NameNode,但這種設計存在單點故障問題,官方提供了兩種解決方案:
通過增加一個Secondary NameNode節點,處於Standby的狀態,與Active的NameNode同時運行。當Active的節點出現故障時,切換到Secondary節點。
為了保證Secondary節點能夠隨時頂替上去,Standby節點需要定時同步Active節點的事務日誌來更新本地的文件系統目錄樹信息,同時DataNode需要配置所有NameNode的位置,並向所有狀態的NameNode發送塊列表信息和心跳。
同步事務日誌來更新目錄樹由JournalNode的守護進程來完成,簡稱為QJM,一個NameNode對應一個QJM進程,當Active節點執行任何命名空間文件目錄樹修改時,它會將修改記錄持久化到大多數QJM中,Standby節點從QJM中監聽並讀取編輯事務日誌內容,並將編輯日誌應用到自己的命名空間。發生故障轉移時,Standby節點將確保在將自身提升為Active狀態之前,從QJM讀取所有編輯內容。
注意,QJM只是實現了數據的備份,當Active節點發送故障時,需要手工提升Standby節點為Active節點。如果要實現NameNode故障自動轉移,則需要配套ZKFC組件來實現,ZKFC也是獨立運行的一個守護進程,基於zookeeper來實現選舉和自動故障轉移。
雖然HDFS HA解決了「單點故障」問題,但是在系統擴展性、整體性能和隔離性方面仍然存在問題:
HDFS HA本質上還是單名稱節點。HDFS聯邦可以解決以上三個方面問題。
在HDFS聯邦中,設計了多個相互獨立的NN,使得HDFS的命名服務能夠水平擴展,這些NN分別進行各自命名空間和塊的管理,不需要彼此協調。每個DN要向集群中所有的NN注冊,並周期性的發送心跳信息和塊信息,報告自己的狀態。
HDFS聯邦擁有多個獨立的命名空間,其中,每一個命名空間管理屬於自己的一組塊,這些屬於同一個命名空間的塊組成一個「塊池」。每個DN會為多個塊池提供塊的存儲,塊池中的各個塊實際上是存儲在不同DN中的。