1.1 數據塊
1.2 NameNode和DataNode
1.2.1 管理者:Namenode
1.2.1 工作者:Datanode
1.3 Secondary Namenode
1.4 HDFS的優缺點
2. HDFS的架構
2.1 HDFS架構之NameNode和DataNode
2.2 Namenode和Secondary Namenode運行關系
3. HDFS文件的讀寫流程
3.1 HDFS文件的讀取
3.2 HDFS文件的寫入
1. HDFS中的一些概念
HDFS(Hadoop Distributed File System):分布式文件系統,將一個文件分成多個塊,分別存儲(拷貝)到不同的節點上,它是Hadoop體系中數據存儲管理的基礎。它是一個高度容錯的系統,能檢測和應對硬件故障,用於在低成本的通用硬件上運行。HDFS簡化了文件的一致性模型,通過流式數據訪問,提供高吞吐量應用程序數據訪問功能,適合帶有大型數據集的應用程序。
1.1 數據塊
每個磁盤都有數據塊的概念,在HDFS中也有數據塊的概念,HDFS中的所有文件都是分割成塊存儲在Datanode上的,每個塊默認64M。。每個塊都有多個副本存儲在不同的機器上:默認有3個副本,3個副本不可能存放在同一個機器上。
HDFS副本存放策略

以下是HDFS文件存儲架構圖
黃色:表示每台機器
綠色:文件被分割出的塊

例如:
上圖中part-0文件,有2個塊。塊1和塊3只在2個機器上分別出現過2次。
上圖中part-1文件,有3個塊。塊2,4,5分別在不同的機器上各出現3次
HDFS中也可以顯示塊信息,使用fsck命令
例如:下面的命令將列出文件系統中各個文件由哪些塊構成
$ hadoop fsck / -files -blocks
1.2 NameNode和DataNode
HDFS的設計是主(Master)從(Slave)結構的。也就是,一個管理者(NameNode)和多個工作者(DataNode)組成。
1.2.1 管理者:Namenode
NameNode是主節點,它是一個中心服務器,負責管理整個文件系統的命名空間和控制着客戶端對文件的訪問。它不保存文件的內容,而是保存着文件的元數據(文件名稱,所在目錄,文件權限,文件擁有者,文件有多少塊,每個塊有多少副本,塊都存在哪些節點上)。
Namenode負責文件的元數據操作,Datanode處理文件內容的讀寫請求。
跟文件相關的流不經過Namenode,只會詢問該文件跟哪個Datanode有關系。
副本存放在哪些Datanode上是由Namenode來控制。讀取文件時,Namenode盡量讓用戶先讀取最近的副本。
Namenode全權管理數據塊的復制,周期性的從集群中的每個Datanode接收心跳信號和塊狀態報告。
Namenode和Datanode就是通過這兩種方式來進行通信:
心跳信號:意味着該Datanode節點工作正常
塊狀態報告:包含了一個該Datanode上所有數據塊的列表
元數據保存在內存中
Namenode維護着整個文件系統樹以及樹內的所有文件。這些信息以兩個文件的形式永久保存在磁盤上。命名空間鏡像文件(fsimage)和操作日志(fsedits)文件
1. fsimage是什么?
fsimage是元數據鏡像文件:Namenode啟動后,文件的元數據被加載到內存中,加載到內存后也會把這些元數據寫入到本地的磁盤中,這個文件就是fsimage文件。
元數據鏡像在內存中保存一份最新的,內存中的鏡像=fsimage+fsedit
2. fsedits是什么?
fsedits是元數據操作日志文件:客戶端要對文件進行讀寫操作,在這些操作產生的日志就存在了fsedit文件中。
1.2.1 工作者:Datanode
DataNode是從節點,它的作用很簡單,就是存儲文件的塊數據。以及塊數據的校驗和。
一個數據塊在Ddtanode以文件存儲在磁盤上,包括兩個文件:數據本身和元數據(數據塊的長度,塊數據的校驗和,時間戳)
Datanode啟動后向Namenode注冊,通過后,周期性(1小時)的向Namenode上報所有塊信息。
心跳是3秒一次,如果超過10分鍾沒有收到某個Datanode的心跳。則認為該節點不可用。
1.3 Secondary Namenode
Secondary Namenode:Secondary表示助手的意思,也就是說Secondary Namenode表示NameNode的助手,輔助NameNode工作的一個節點。要了解Secondary Namenode節點都輔助NameNode做了哪些工作,我們需要先回顧下NameNode是做什么的?
NameNode是HDFS中的一個主節點,主要是來管理其他DataNode從節點。它存儲了HDFS系統的namespace和控制着客戶端對HDFS文件系統的訪問。NameNode在維護整個文件系統樹的時候是以兩個文件的形式永久保存在磁盤上。鏡像文件(fsimage)和操作日志文件(fsedits)。考慮以下,這兩個文件一直這樣運行存在着有什么問題?
- fsedits操作日志文件會越來越大,因為它保存着客戶端對HDFS文件系統的訪問日志。
- 只有在NameNode重啟后,edits logs才會合並到fsimage中,產生一個新的文件系統快照。但是NameNode是很少重啟的。
為了保證edit logs文件不會太大和fsimage是一個最新的文件,此時需要一個節點來備份這些文件。定期的合並這兩個文件然后再推送給NameNode,這樣就減輕NameNode工作的壓力,同時也保證了假如Namenode節點宕機后數據無法恢復問題。雖然可能不會把所有的數據全部恢復出來,但是至少丟失的很少。
所以,Secondary Namenode做的就是這些輔助工作
- Secondary NameNode所做的不過是在文件系統中設置一個檢查點來幫助NameNode更好的工作。它不是要取代掉NameNode也不是NameNode的備份。
- SecondaryNameNode有兩個作用,一是鏡像備份,二是日志與鏡像的定期合並。兩個過程同時進行,稱為checkpoint
在core-site.xml配置文件中有2個參數可配置,但一般來說我們不做修改。fs.checkpoint.period表示多長時間記錄一次hdfs的鏡像。默認是1小時。fs.checkpoint.size表示一次記錄多大的size,默認64M。
<property>
<name>fs.checkpoint.period</name>
<value>3600</value>
<description>The number of seconds between two periodic checkpoints.
</description>
</property>
<property>
<name>fs.checkpoint.size</name>
<value>67108864</value>
<description>The size of the current edit log (in bytes) that triggers a periodic checkpoint even if the fs.checkpoint.period hasn’t expired.
</description>
</property>
可以參考這篇博客,寫的還是很詳細的Secondary NameNode:它究竟有什么作用?
1.4 HDFS的優缺點
優點:
- 高容錯性
數據自動保存多個副本
副本丟失后,自動恢復 - 適合批處理
移動計算而非數據
數據位置暴露給計算框架 - 適合大數據處理
GB、TB、甚至PB級數據
百萬規模以上的文件數量
10K+節點規模 - 流式文件訪問
一次性寫入,多次讀取
保證數據一致性 - 可構建在廉價機器上
通過多副本提高可靠性
提供了容錯和恢復機制
缺點:
- 低延遲與高吞吐率的數據訪問 ,比如毫秒級
- 小文件存取
占用NameNode大量內存
尋道時間超過讀取時間 - 並發寫入、文件隨機修改
一個文件同一個時間只能有一個寫者
僅支持append
2. HDFS的架構
HDFS以流式數據訪問(一次寫入,多次讀取)模式來存儲超大文件,運行於商用硬件集群上。超大文件是指GB,TB,PB的文件。目前已經有存儲到PB級別的Hadoop集群了。
計算機字節關系

Hadoop1.x HDFS官方架構圖

2.1 HDFS架構之NameNode和DataNode
HDFS架構圖

- 客戶端(HDFS Client):如果想對文件進行讀寫的話,首先需要通過Namenode來獲取一些信息。Namenode存儲着命名空間(namespace)和元數據(metadata)
客戶端有如下工作:- 文件的切分
- 與Namenode交互,獲取文件位置信息
- 與Datanode交互,讀取或者寫入數據
- 管理HDFS
- 訪問HDFS(瀏覽器,Shell命令,JavaAPI)
- 輔助節點(Secondary):用於輔助Namenode工作,分擔其工作量。主要工作是nameSpace的冷備份工作,並非熱備份。定期將Namenode的鏡像文件(fsimage)和操作日志(fsedit)進行合並,然后推送給Namenode
1. fsimage是什么?
是元數據鏡像文件:Namenode啟動后,文件的元數據被加載到內存中,加載到內存后也會把這些元數據寫入到本地的磁盤中,這個文件就是fsimage文件。
元數據鏡像在內存中保存一份最新的,內存中的鏡像=fsimage+fsedit
2. fsedits是什么?
是元數據操作日志文件:客戶端要對文件進行讀寫操作,在這些操作產生的日志就存在了fsedit文件中。 - 數據節點(Datanode):Namenode和Datanode通信是通過心跳和塊報告。每個文件被分割成不同的塊,存在不同的機器的本地磁盤上。
2.2 Namenode和Secondary Namenode運行關系
Secondarynamenode工作原理
日志與鏡像的定期合並總共分以下五步:
- Secondary Namenode通知Namenode切換editlog
- Secondary Namenode通過Http方式從Namenode獲取fsimage和editlog
- Secondary Namenode將fsimage載入內存,然后開始合並editlog
- Secondary Namenode將新的fsimage發回給Namenode
- Namenode收到fsiamge后將新的fsimage替換舊的fsimage
3. HDFS文件的讀寫流程
3.1 HDFS文件的讀取
HDFS文件讀取:

- 首先調用FileSystem對象的open方法,其實是一個DistributedFileSystem的實例
- DistributedFileSystem通過rpc獲得文件的第一批個block的locations,同一block按照重復數會返回多個locations,這些locations按照hadoop拓撲結構排序,距離客戶端近的排在前面.
- 前兩步會返回一個FSDataInputStream對象,該對象會被封裝成DFSInputStream對象,DFSInputStream可以方便的管理datanode和namenode數據流。客戶端調用read方法,DFSInputStream最會找出離客戶端最近的datanode並連接。
- 數據從datanode源源不斷的流向客戶端。
- 如果第一塊的數據讀完了,就會關閉指向第一塊的datanode連接,接着讀取下一塊。這些操作對客戶端來說是透明的,客戶端的角度看來只是讀一個持續不斷的流。
- 如果第一批block都讀完了,DFSInputStream就會去namenode拿下一批blocks的location,然后繼續讀,如果所有的塊都讀完,這時就會關閉掉所有的流。
3.2 HDFS文件的寫入
HDFS文件寫入:

- 客戶端通過調用DistributedFileSystem的create方法創建新文件
- DistributedFileSystem通過RPC調用namenode去創建一個沒有blocks關聯的新文件,創建前,namenode會做各種校驗,比如文件是否存在,客戶端有無權限去創建等。如果校驗通過,namenode就會記錄下新文件,否則就會拋出IO異常.
- 前兩步結束后會返回FSDataOutputStream的對象,和讀文件的時候相似,FSDataOutputStream被封裝成DFSOutputStream,DFSOutputStream可以協調namenode和datanode。客戶端開始寫數據到DFSOutputStream,DFSOutputStream會把數據切成一個個小packet,然后排成隊列data quene。
- DataStreamer會去處理接受data quene,他先問詢namenode這個新的block最適合存儲的在哪幾個datanode里,比如重復數是3,那么就找到3個最適合的datanode,把他們排成一個pipeline.DataStreamer把packet按隊列輸出到管道的第一個datanode中,第一個datanode又把packet輸出到第二個datanode中,以此類推。
- DFSOutputStream還有一個對列叫ack quene,也是有packet組成,等待datanode的收到響應,當pipeline中的所有datanode都表示已經收到的時候,這時akc quene才會把對應的packet包移除掉。
- 客戶端完成寫數據后調用close方法關閉寫入流
- DataStreamer把剩余得包都刷到pipeline里然后等待ack信息,收到最后一個ack后,通知datanode把文件標示為已完成。
讀寫流程參考自:HDFS筆記(特點、原理與基本架構)
