3.1分布式文件系統
3.1.1計算機集群結構
分布式文件系統把文件分布存儲到多個計算機節點上,成千上萬的計算機節點構成計算機集群。
與之前使用多個處理器和專用高級硬件的並行化處理裝置不同的是,目前的分布式文件系統所采用的計算機集群,都由普通硬件構成的,這就大大降低了硬件上的開銷
3.1.2分布式文件系統的結構
分布式文件系統在物理結構上是由計算機集群中的多個節點構成的,這些節點分為兩類,一類叫“主節點”(Master Node)或者也被稱為“名稱節點”(NameNode),另一類叫“從節點”(Slave Node)或者也被稱為“數據節點”(DataNode)
3.2HDFS簡介
總體而言,HDFS要實現以下目標:
- 兼容廉價的硬件設備
- 流數據讀寫
- 大數據集
- 簡單的文件模型
- 強大的跨平台兼容性
HDFS特殊的設計,在實現上述優良特性的同時,也使得自身具有一些應用局限性,主要包括以下幾個方面:
- 不適合低延遲數據訪問
- 無法高效存儲大量小文件
- 不支持多用戶寫入及任意修改文件
3.3HDFS相關概念
3.3.1塊
HDFS默認一個塊64MB,一個文件被分成多個塊,以塊作為存儲單位
塊的大小遠遠大於普通文件系統,可以最小化尋址開銷
HDFS采用抽象的塊概念可以帶來以下幾個明顯的好處:
支持大規模文件存儲:文件以塊為單位進行存儲,一個大規模文件可以被分拆成若干個文件塊,不同的文件塊可以被分發到不同的節點上,因此,一個文件的大小不會受到單個節點的存儲容量的限制,可以遠遠大於網絡中任意節點的存儲容量。
簡化系統設計:首先,大大簡化了存儲管理,因為文件塊大小是固定的,這樣就可以很容易計算出一個節點可以存儲多少文件塊;其次,方便了元數據的管理,元數據不需要和文件塊一起存儲,可以由其他系統負責管理元數據。
適合數據備份:每個文件塊都可以冗余存儲到多個節點上,大大提高了系統的容錯性和可用性。
3.3.2名稱節點和數據節點
NameNode | DataNode |
存儲元數據 | 存儲文件內容 |
元數據保存在內存中 | 文件內容保存在磁盤 |
保存文件block,datanode之間的映射關系 | 維護了block id到datanode本地文件的映射關系 |
名稱節點的數據結構
在HDFS中,名稱節點(NameNode)負責管理分布式文件系統的命名空間(Namespace),保存了兩個核心的數據結構,即FsImage和EditLog
FsImage用於維護文件系統樹以及文件樹中所有的文件和文件夾元數據
操作日志文件EditLog中記錄了所有針對文件的創建、刪除、重命名等操作
名稱節點記錄了每個文件中各個塊所在的數據節點的位置信息
FsImage文件
FsImage文件包含文件系統中所有目錄和文件inode的序列化形式。每個inode是一個文件或目錄的元數據的內部表示,並包含此類信息:文件的復制等級、修改和訪問時間、訪問權限、塊大小以及組成文件的塊。對於目錄,則存儲修改時間、權限和配額元數據。
FsImage文件沒有記錄塊存儲在哪個數據節點。而是由名稱節點把這些映射保留在內存中,當數據節點加入HDFS集群時,數據節點會把自己所包含的塊列表告知給名稱節點,此后會定期執行這種告知操作,以確保名稱節點的塊映射是最新的。
名稱節點的啟動
在名稱節點啟動的時候,它會將FsImage文件中的內容加載到內存中,之后再執行EditLog文件中的各項操作,使得內存中的元數據和實際的同步,存在內存中的元數據支持客戶端的讀操作。
一旦在內存中成功建立文件系統元數據的映射,則創建一個新的FsImage文件和一個空的EditLog文件。
名稱節點起來之后,HDFS中的更新操作會重新寫到EditLog文件中,因為FsImage文件一般都很大(GB級別的很常見),如果所有的更新操作都往FsImage文件中添加,這樣會導致系統運行的十分緩慢,但是,如果往EditLog文件里面寫就不會這樣,因為EditLog 要小很多。每次執行寫操作之后,且在向客戶端發送成功代碼之前,edits文件都需要同步更新。
名稱節點運行期間EditLog不斷變大的問題
在名稱節點運行期間,HDFS的所有更新操作都是直接寫到EditLog中,久而久之, EditLog文件將會變得很大
雖然這對名稱節點運行時候是沒有什么明顯影響的,但是,當名稱節點重啟的時候,名稱節點需要先將FsImage里面的所有內容映像到內存中,然后再一條一條地執行EditLog中的記錄,當EditLog文件非常大的時候,會導致名稱節點啟動操作非常慢,而在這段時間內HDFS系統處於安全模式,一直無法對外提供寫操作,影響了用戶的使用
如何解決?答案是:SecondaryNameNode第二名稱節點
第二名稱節點是HDFS架構中的一個組成部分,它是用來保存名稱節點中對HDFS 元數據信息的備份,並減少名稱節點重啟的時間。SecondaryNameNode一般是單獨運行在一台機器上
SecondaryNameNode的工作情況:
(1)SecondaryNameNode會定期和NameNode通信,請求其停止使用EditLog文件,暫時將新的寫操作寫到一個新的文件edit.new上來,這個操作是瞬間完成,上層寫日志的函數完全感覺不到差別;
(2)SecondaryNameNode通過HTTP GET方式從NameNode上獲取到FsImage和EditLog文件,並下載到本地的相應目錄下;
(3)SecondaryNameNode將下載下來的FsImage載入到內存,然后一條一條地執行EditLog文件中的各項更新操作,使得內存中的FsImage保持最新;這個過程就是EditLog和FsImage文件合並;
(4)SecondaryNameNode執行完(3)操作之后,會通過post方式將新的FsImage文件發送到NameNode節點上;
(5)NameNode將從SecondaryNameNode接收到的新的FsImage替換舊的FsImage文件,同時將edit.new替換EditLog文件,通過這個過程EditLog就變小了。
數據節點(DataNode)
數據節點是分布式文件系統HDFS的工作節點,負責數據的存儲和讀取,會根據客戶端或者是名稱節點的調度來進行數據的存儲和檢索,並且向名稱節點定期發送自己所存儲的塊的列表。
每個數據節點中的數據會被保存在各自節點的本地Linux文件系統中。
3.4HDFS體系結構
3.4.1HDFS體系結構概述
HDFS采用了主從(Master/Slave)結構模型,一個HDFS集群包括一個名稱節點(NameNode)和若干個數據節點(DataNode)(如圖所示)。名稱節點作為中心服務器,負責管理文件系統的命名空間及客戶端對文件的訪問。集群中的數據節點一般是一個節點運行一個數據節點進程,負責處理文件系統客戶端的讀/寫請求,在名稱節點的統一調度下進行數據塊的創建、刪除和復制等操作。每個數據節點的數據實際上是保存在本地Linux文件系統中的。
3.4.2HDFS命名空間管理
HDFS的命名空間包含目錄、文件和塊
在HDFS1.0體系結構中,在整個HDFS集群中只有一個命名空間,並且只有唯一一個名稱節點,該節點負責對這個命名空間進行管理
HDFS使用的是傳統的分級文件體系,因此,用戶可以像使用普通文件系統一樣,創建、刪除目錄和文件,在目錄間轉移文件,重命名文件等
3.4.3通信協議
HDFS是一個部署在集群上的分布式文件系統,因此,很多數據需要通過網絡進行傳輸
所有的HDFS通信協議都是構建在TCP/IP協議基礎之上的
客戶端通過一個可配置的端口向名稱節點主動發起TCP連接,並使用客戶端協議與名稱節點進行交互
名稱節點和數據節點之間則使用數據節點協議進行交互
客戶端與數據節點的交互是通過RPC(Remote Procedure Call)來實現的。在設計上,名稱節點不會主動發起RPC,而是響應來自客戶端和數據節點的RPC請求
3.4.4客戶端
客戶端是用戶操作HDFS最常用的方式,HDFS在部署時都提供了客戶端
HDFS客戶端是一個庫,暴露了HDFS文件系統接口,這些接口隱藏了HDFS實現中的大部分復雜性
嚴格來說,客戶端並不算是HDFS的一部分
客戶端可以支持打開、讀取、寫入等常見的操作,並且提供了類似Shell的命令行方式來訪問HDFS中的數據
此外,HDFS也提供了Java API,作為應用程序訪問文件系統的客戶端編程接口
3.4.5HDFS體系結構的局限性
HDFS只設置唯一一個名稱節點,這樣做雖然大大簡化了系統設計,但也帶來了一些明顯的局限性,具體如下:
(1)命名空間的限制:名稱節點是保存在內存中的,因此,名稱節點能夠容納的對象(文件、塊)的個數會受到內存空間大小的限制。
(2)性能的瓶頸:整個分布式文件系統的吞吐量,受限於單個名稱節點的吞吐量。
(3)隔離問題:由於集群中只有一個名稱節點,只有一個命名空間,因此,無法對不同應用程序進行隔離。
(4)集群的可用性:一旦這個唯一的名稱節點發生故障,會導致整個集群變得不可用。
3.5HDFS存儲原理
3.5.1冗余數據保存
作為一個分布式文件系統,為了保證系統的容錯性和可用性,HDFS采用了多副本方式對數據進行冗余存儲,通常一個數據塊的多個副本會被分布到不同的數據節點上,如圖所示,數據塊1被分別存放到數據節點A和C上,數據塊2被存放在數據節點A和B上。這種多副本方式具有以下幾個優點:
(1)加快數據傳輸速度
(2)容易檢查數據錯誤
(3)保證數據可靠性
3.5.2數據存取策略
1、數據存放
第一個副本:放置在上傳文件的數據節點;如果是集群外提交,則隨機挑選一台磁盤不太滿、CPU不太忙的節點
第二個副本:放置在與第一個副本不同的機架的節點上
第三個副本:與第一個副本相同機架的其他節點上
更多副本:隨機節點
Block的副本放置策略
2、數據讀取
HDFS提供了一個API可以確定一個數據節點所屬的機架ID,客戶端也可以調用API獲取自己所屬的機架ID
當客戶端讀取數據時,從名稱節點獲得數據塊不同副本的存放位置列表,列表中包含了副本所在的數據節點,可以調用API來確定客戶端和這些數據節點所屬的機架ID,當發現某個數據塊副本對應的機架ID和客戶端對應的機架ID相同時,就優先選擇該副本讀取數據,如果沒有發現,就隨機選擇一個副本讀取數據
3.5.3數據錯誤與恢復
HDFS具有較高的容錯性,可以兼容廉價的硬件,它把硬件出錯看作一種常態,而不是異常,並設計了相應的機制檢測數據錯誤和進行自動恢復,主要包括以下幾種情形:名稱節點出錯、數據節點出錯和數據出錯。
1、名稱節點出錯
名稱節點保存了所有的元數據信息,其中,最核心的兩大數據結構是FsImage和Editlog,如果這兩個文件發生損壞,那么整個HDFS實例將失效。因此,HDFS設置了備份機制,把這些核心文件同步復制到備份服務器SecondaryNameNode上。當名稱節點出錯時,就可以根據備份服務器SecondaryNameNode中的FsImage和Editlog數據進行恢復。
2、數據節點出錯
每個數據節點會定期向名稱節點發送“心跳”信息,向名稱節點報告自己的狀態
當數據節點發生故障,或者網絡發生斷網時,名稱節點就無法收到來自一些數據節點的心跳信息,這時,這些數據節點就會被標記為“宕機”,節點上面的所有數據都會被標記為“不可讀”,名稱節點不會再給它們發送任何I/O請求
這時,有可能出現一種情形,即由於一些數據節點的不可用,會導致一些數據塊的副本數量小於冗余因子
名稱節點會定期檢查這種情況,一旦發現某個數據塊的副本數量小於冗余因子,就會啟動數據冗余復制,為它生成新的副本
HDFS和其它分布式文件系統的最大區別就是可以調整冗余數據的位置
3、數據出錯
網絡傳輸和磁盤錯誤等因素,都會造成數據錯誤
客戶端在讀取到數據后,會采用md5和sha1對數據塊進行校驗,以確定讀取到正確的數據
在文件被創建時,客戶端就會對每一個文件塊進行信息摘錄,並把這些信息寫入到同一個路徑的隱藏文件里面
當客戶端讀取文件的時候,會先讀取該信息文件,然后,利用該信息文件對每個讀取的數據塊進行校驗,如果校驗出錯,客戶端就會請求到另外一個數據節點讀取該文件塊,並且向名稱節點報告這個文件塊有錯誤,名稱節點會定期檢查並且重新復制這個塊
3.6HDFS數據讀寫過程
讀取文件
寫入文件
FileSystem是一個通用文件系統的抽象基類,可以被分布式文件系統繼承,所有可能使用Hadoop文件系統的代碼,都要使用這個類
Hadoop為FileSystem這個抽象類提供了多種具體實現
DistributedFileSystem就是FileSystem在HDFS文件系統中的具體實現
FileSystem的open()方法返回的是一個輸入流FSDataInputStream對象,在HDFS文件系統中,具體的輸入流就是DFSInputStream;FileSystem中的create()方法返回的是一個輸出流FSDataOutputStream對象,在HDFS文件系統中,具體的輸出流就是DFSOutputStream。
3.6.1讀數據的過程
3.6.2寫數據的過程
3.7HDFS編程實踐