天天看點

大資料技術原理與應用 第三章 分布式檔案系統HDFS

廈門大學林子雨老師課程 —— 大資料技術原理與應用 學習筆記

參考資料:

http://dblab.xmu.edu.cn/post/bigdata-online-course/#lesson0

https://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html

1. Hadoop分布式檔案系統(HDFS)被設計成适合運作在通用硬體(commodity hardware)上的分布式檔案系統。它和現有的分布式檔案系統有很多共同點。但同時,它和其他的分布式檔案系統的差別也是很明顯的。HDFS是一個高度容錯性的系統,适合部署在廉價的機器上。HDFS能提供高吞吐量的資料通路,非常适合大規模資料集上的應用。HDFS放寬了一部分POSIX限制,來實作流式讀取檔案系統資料的目的。

2. 前提和設計目标

硬體錯誤

硬體錯誤是常态而不是異常。HDFS可能由成百上千的伺服器所構成,每個伺服器上存儲着檔案系統的部分資料。我們面對的現實是構成系統的元件數目是巨大的,而且任一元件都有可能失效,這意味着總是有一部分HDFS的元件是不工作的。是以錯誤檢測和快速、自動的恢複是HDFS最核心的架構目标。

流式資料通路

運作在HDFS上的應用和普通的應用不同,需要流式通路它們的資料集。HDFS的設計中更多的考慮到了資料批處理,而不是使用者互動處理。比之資料通路的低延遲問題,更關鍵的在于資料通路的高吞吐量。POSIX标準設定的很多硬性限制對HDFS應用系統不是必需的。為了提高資料的吞吐量,在一些關鍵方面對POSIX的語義做了一些修改。

大規模資料集

運作在HDFS上的應用具有很大的資料集。HDFS上的一個典型檔案大小一般都在G位元組至T位元組。是以,HDFS被調節以支援大檔案存儲。它應該能提供整體上高的資料傳輸帶寬,能在一個叢集裡擴充到數百個節點。一個單一的HDFS執行個體應該能支撐數以千萬計的檔案。

簡單的一緻性模型

HDFS應用需要一個“一次寫入多次讀取”的檔案通路模型。一個檔案經過建立、寫入和關閉之後就不需要改變。這一假設簡化了資料一緻性問題,并且使高吞吐量的資料通路成為可能。Map/Reduce應用或者網絡爬蟲應用都非常适合這個模型。目前還有計劃在将來擴充這個模型,使之支援檔案的附加寫操作。

“移動計算比移動資料更劃算”

一個應用請求的計算,離它操作的資料越近就越高效,在資料達到海量級别的時候更是如此。因為這樣就能降低網絡阻塞的影響,提高系統資料的吞吐量。将計算移動到資料附近,比之将資料移動到應用所在顯然更好。HDFS為應用提供了将它們自己移動到資料附近的接口。

異構軟硬體平台間的可移植性

HDFS在設計的時候就考慮到平台的可移植性。這種特性友善了HDFS作為大規模資料應用平台的推廣。

3. HDFS預設一個塊64MB,一個檔案被分成多個塊,以塊作為存儲機關。

4. NameNode和DataNode

大資料技術原理與應用 第三章 分布式檔案系統HDFS

(1)在HDFS中,名稱節點(NameNode)負責管理分布式檔案系統的命名空間(Namespace),儲存了兩個核心的資料結構,即FsImage和EditLog

FsImage用于維護檔案系統樹以及檔案樹中所有的檔案和檔案夾的中繼資料

記錄檔檔案EditLog中記錄了所有針對檔案的建立、删除、重命名等操作

名稱節點記錄了每個檔案中各個塊所在的資料節點的位置資訊

FsImage檔案包含檔案系統中所有目錄和檔案inode的序列化形式。每個inode是一個檔案或目錄的中繼資料的内部表示,并包含此類資訊:檔案的複制等級、修改和通路時間、通路權限、塊大小以及組成檔案的塊。對于目錄,則存儲修改時間、權限和配額中繼資料

FsImage檔案沒有記錄塊存儲在哪個資料節點。而是由名稱節點把這些映射保留在記憶體中,當資料節點加入HDFS叢集時,資料節點會把自己所包含的塊清單告知給名稱節點,此後會定期執行這種告知操作,以確定名稱節點的塊映射是最新的。

(2)名稱節點的啟動

在名稱節點啟動的時候,它會将FsImage檔案中的内容加載到記憶體中,之後再執行EditLog檔案中的各項操作,使得記憶體中的中繼資料和實際的同步,存在記憶體中的中繼資料支援用戶端的讀操作。

一旦在記憶體中成功建立檔案系統中繼資料的映射,則建立一個新的FsImage檔案和一個空的EditLog檔案

名稱節點起來之後,HDFS中的更新操作會重新寫到EditLog檔案中,因為FsImage檔案一般都很大(GB級别的很常見),如果所有的更新操作都往FsImage檔案中添加,這樣會導緻系統運作的十分緩慢,但是,如果往EditLog檔案裡面寫就不會這樣,因為EditLog 要小很多。每次執行寫操作之後,且在向用戶端發送成功代碼之前,edits檔案都需要同步更新。

(3)名稱節點運作期間EditLog不斷變大的問題

在名稱節點運作期間,HDFS的所有更新操作都是直接寫到EditLog中,久而久之, EditLog檔案将會變得很大。

雖然這對名稱節點運作時候是沒有什麼明顯影響的,但是,當名稱節點重新開機的時候,名稱節點需要先将FsImage裡面的所有内容映像到記憶體中,然後再一條一條地執行EditLog中的記錄,當EditLog檔案非常大的時候,會導緻名稱節點啟動操作非常慢,而在這段時間内HDFS系統處于安全模式,一直無法對外提供寫操作,影響了使用者的使用。

解決方法:第二名稱節點

第二名稱節點是HDFS架構中的一個組成部分,它是用來儲存名稱節點中對HDFS 中繼資料資訊的備份,并減少名稱節點重新開機的時間。Secondary NameNode一般是單獨運作在一台機器上。

Secondary NameNode的工作情況:

(a)SecondaryNameNode會定期和NameNode通信,請求其停止使用EditLog檔案,暫時将新的寫操作寫到一個新的檔案edit.new上來,這個操作是瞬間完成,上層寫日志的函數完全感覺不到差别;

(b)SecondaryNameNode通過HTTP GET方式從NameNode上擷取到FsImage和EditLog檔案,并下載下傳到本地的相應目錄下;

(c)SecondaryNameNode将下載下傳下來的FsImage載入到記憶體,然後一條一條地執行EditLog檔案中的各項更新操作,使得記憶體中的FsImage保持最新;這個過程就是EditLog和FsImage檔案合并;

(d)SecondaryNameNode執行完(c)操作之後,會通過post方式将新的FsImage檔案發送到NameNode節點上

(e)NameNode将從SecondaryNameNode接收到的新的FsImage替換舊的FsImage檔案,同時将edit.new替換EditLog檔案,通過這個過程EditLog就變小了

(4)Namenode全權管理資料塊的複制,它周期性地從叢集中的每個Datanode接收心跳信号和塊狀态報告(Blockreport)。接收到心跳信号意味着該Datanode節點工作正常。塊狀态報告包含了一個該Datanode上所有資料塊的清單。

(5)DataNode

資料節點是分布式檔案系統HDFS的工作節點,負責資料的存儲和讀取,會根據用戶端或者是名稱節點的排程來進行資料的存儲和檢索,并且向名稱節點定期發送自己所存儲的塊的清單。

每個資料節點中的資料會被儲存在各自節點的本地Linux檔案系統中。

5. 資料複制

HDFS将每個檔案存儲成一系列的資料塊,除了最後一個,所有的資料塊都是同樣大小的。為了容錯,檔案的所有資料塊都會有副本。副本系數一般為3,其存放政策為:

第一個副本:放置在上傳檔案的資料節點;如果是叢集外送出,則随機挑選一台磁盤不太滿、CPU不太忙的節點

第二個副本:放置在與第一個副本不同的機架的節點上

第三個副本:與第一個副本相同機架的其他節點上

更多副本:随機節點

6. 資料錯誤與恢複

(1)名稱節點出錯

名稱節點儲存了所有的中繼資料資訊,其中,最核心的兩大資料結構是FsImage和Editlog,如果這兩個檔案發生損壞,那麼整個HDFS執行個體将失效。是以,HDFS設定了備份機制,把這些核心檔案同步複制到備份伺服器SecondaryNameNode上。當名稱節點出錯時,就可以根據備份伺服器SecondaryNameNode中的FsImage和Editlog資料進行恢複。

(2)資料節點出錯

每個資料節點會定期向名稱節點發送“心跳”資訊,向名稱節點報告自己的狀态

當資料節點發生故障,或者網絡發生斷網時,名稱節點就無法收到來自一些資料節點的心跳資訊,這時,這些資料節點就會被标記為“當機”,節點上面的所有資料都會被标記為“不可讀”,名稱節點不會再給它們發送任何I/O請求

這時,有可能出現一種情形,即由于一些資料節點的不可用,會導緻一些資料塊的副本數量小于備援因子

名稱節點會定期檢查這種情況,一旦發現某個資料塊的副本數量小于備援因子,就會啟動資料備援複制,為它生成新的副本

HDFS和其它分布式檔案系統的最大差別就是可以調整備援資料的位置

(3)資料出錯

網絡傳輸和磁盤錯誤等因素,都會造成資料錯誤

用戶端在讀取到資料後,會采用md5和sha1對資料塊進行校驗,以确定讀取到正确的資料

在檔案被建立時,用戶端就會對每一個檔案塊進行資訊摘錄,并把這些資訊寫入到同一個路徑的隐藏檔案裡面

當用戶端讀取檔案的時候,會先讀取該資訊檔案,然後,利用該資訊檔案對每個讀取的資料塊進行校驗,如果校驗出錯,用戶端就會請求到另外一個資料節點讀取該檔案塊,并且向名稱節點報告這個檔案塊有錯誤,名稱節點會定期檢查并且重新複制這個塊