大資料 | 分散式檔案系統 HDFS

Max_Lyu發表於2021-07-09
HDFS全稱Hadoop Distributed File System,看名字就知道是Hadoop生態的一個元件,它是一個分散式檔案系統。
它的出現解決了獨立機器儲存大資料集的壓力,它將資料集進行切分,儲存在若干臺計算機上。

HDFS 的特點與應用場景

適合儲存大檔案

HDFS 支援 GB 級別甚至 TB 級別的檔案,它會把大檔案切分成若干個塊儲存在不同的節點上,在進行大檔案讀寫時採用並行的方式提高資料的吞吐量。

容錯性高

HDFS有多副本機制,它會自動儲存副本到不同的節點。即使有一臺節點當機了也不會丟失資料。

適用於流式的資料訪問

HDFS 適用於批量資料的處理,不適合互動式處理。它設計的目標是通過流式的資料訪問保證高吞吐量,不適合對低延遲使用者響應的應用。

適用於讀多寫少場景

HDFS 中的檔案支援一次寫入、多次讀取,寫入操作是以追加的方式(append)新增在檔案末尾,不支援對檔案的任意位置進行修改。

HDFS的相關概念

資料塊(Block)

和磁碟的資料塊概念相似,磁碟中的塊是資料讀寫的最小單位,而HDFS中檔案被切分成多個塊,作為獨立的儲存單元,但是比磁碟的塊大得多,預設為128MB,且小於一個塊大小的檔案不會佔據整個塊的空間。
需要說明的一點是,資料塊不能設定太小,否則在查詢的過程中會造成定址時間長,導致效率慢;另一方面,資料塊太小會造成很多小檔案,進而造成後設資料也更多,佔用記憶體就更多。

NameNode和DataNode

HDFS中由NameNode和DataNode組成Master-Slave模式(主從模式)執行,NameNode負責管理檔案系統的名稱空間和檔案後設資料,記錄了每個檔案中各個塊所在的資料節點資訊,而DataNode則是HDFS中的工作節點,負責儲存資料和讀寫操作。簡單理解就是NameNode是主管,DataNode是負責幹活的工人。

Secondary NameNode

若NameNode故障,檔案系統上的檔案將會丟失,因此對NameNode實現容錯很重要,Hadoop中提供了兩種容錯機制,一種是備份那些組成檔案系統後設資料持久狀態的檔案;另一種就是用Secondary NameNode.
需要注意的是,Secondary NameNode執行在獨立的計算機上,它只是一個輔助而不是一個備用,它不能被用於NameNode。它用於定期合併編輯日誌和名稱空間映象,防止編輯日誌過大,在NameNode發生故障時啟用。

塊快取

DataNode進行讀寫操作,一般是從磁碟讀取,但對於讀取頻繁的檔案,可以被快取在DataNode的記憶體中,以提高讀操作的效能。

HDFS 架構

大資料 | 分散式檔案系統 HDFS
Namenode管理後設資料;Datanode儲存Block;Block有多個副本存在不同的節點;節點可以放在不同的機架(Rack);客戶端通過與Namenode與Datanode互動讀取資料(具體的讀寫流程後面講)

機架感知和副本機制

通常,大型Hadoop叢集會分佈在很多機架上。
一般為了提高效率,希望不同節點之間的通訊儘量發生在同一個機架之內,而不是跨機架。
另外為了提高容錯能力,儘可能把資料塊的副本放到多個機架上。
機架感知並不是自動感知的,而是需要管理者告知叢集實現的。
以一個三副本為例,HDFS機架感知和副本機制大概如圖所示
大資料 | 分散式檔案系統 HDFS

讀寫流程

讀操作

簡要流程:
客戶端向NameNode發起讀資料請求;
NameNode響應請求並告訴客戶端要讀的檔案的資料塊位置;
客戶端就近到對應DataNode取數,當資料讀取到達末端,關閉與這個DataNode的連線,並查詢下一個資料塊,直到檔案資料全部讀完;
最後關閉輸出流。
大資料 | 分散式檔案系統 HDFS
詳細流程:
  1. 客戶端通過呼叫 FileSystem 物件的 open() 方法來開啟希望讀取的檔案,對於 HDFS 來說,這個物件是分散式檔案系統的一個例項;
  2. DistributedFileSystem 通過RPC 呼叫 NameNode 以確定檔案起始塊的位置,由於存在多個副本,因此Namenode會返回同一個Block的多個檔案的位置,然後根據叢集拓撲結構排序,就近取;
  3. 前兩步會返回一個 FSDataInputStream 物件,該物件會被封裝成 DFSInputStream 物件,DFSInputStream 可以方便的管理 datanode 和 namenode 資料流,客戶端對這個輸入流呼叫 read() 方法;
  4. 儲存著檔案起始塊的 DataNode 地址的 DFSInputStream 隨即連線距離最近的 DataNode,通過對資料流反覆呼叫 read() 方法,可以將資料從 DataNode 傳輸到客戶端;
  5. 到達塊的末端時,DFSInputStream 會關閉與該 DataNode 的連線,然後尋找下一個塊的最佳 DataNode,這些操作對客戶端來說是透明的,從客戶端的角度來看只是讀一個持續不斷的流;
  6. 一旦客戶端完成讀取,就對 FSDataInputStream 呼叫 close() 方法關閉檔案讀取。

寫操作

簡單流程:
客戶端發起寫資料請求;
NameNode響應請求,然後做一些檢查,比如檢視檔案是否存在,達標則建立檔案;
客戶端將檔案切分成若干個塊,然後上傳,先把第一個塊傳到Datanode1,然後Datanode1再傳給Datanode2,以此類推,傳完為止;
成功後DataNode會返回一個確認佇列給客戶端,客戶端進行效驗,然後客戶端上傳下一個資料塊到DataNode,直到所有資料塊寫入完成;
當所有資料塊全部寫入成功後,客戶端會向NameNode傳送一個反饋並關閉資料流。
大資料 | 分散式檔案系統 HDFS
詳細流程:
  1. 客戶端通過呼叫 DistributedFileSystem 的 create() 方法建立新檔案;
  2. DistributedFileSystem 通過 RPC 呼叫 NameNode 去建立一個沒有 Blocks 關聯的新檔案,建立前 NameNode 會做各種校驗,比如檔案是否存在、客戶端有無許可權去建立等。如果校驗通過,NameNode 會為建立新檔案記錄一條記錄,否則就會丟擲 IO 異常;
  3. 前兩步結束後會返回 FSDataOutputStream 的物件,和讀檔案的時候相似,FSDataOutputStream 被封裝成 DFSOutputStream,DFSOutputStream 可以協調 NameNode 和 Datanode。客戶端開始寫資料到 DFSOutputStream,DFSOutputStream 會把資料切成一個個小的資料包,並寫入內部佇列稱為“資料佇列”(Data Queue);
  4. DataStreamer 會去處理接受 Data Queue,它先問詢 NameNode 這個新的 Block 最適合儲存在哪幾個 DataNode 裡,比如重複數是 3,那麼就找到 3 個最適合的 DataNode,把他們排成一個 pipeline。DataStreamer 把 Packet 按佇列輸出到管道的第一個 Datanode 中,第一個 DataNode 又把 Packet 輸出到第二個 DataNode 中,以此類推;
  5. DFSOutputStream 還有一個佇列叫 Ack Quene,也是由 Packet 組成,等待 DataNode 的收到響應,當 Pipeline 中的所有 DataNode 都表示已經收到的時候,這時 Akc Quene 才會把對應的 Packet 包移除掉;
  6. 客戶端完成寫資料後呼叫 close() 方法關閉寫入流;
  7. DataStreamer 把剩餘的包都刷到 Pipeline 裡然後等待 Ack 資訊,收到最後一個 Ack 後,通知 NameNode 把檔案標示為已完成。

總結

本文簡單講了 HDFS 的特點與應用場景、相關概念、架構、副本機制和機架感知以及讀寫流程。如果覺得有幫到你或者有所收穫,麻煩動動小手點個贊或隨手轉發。
微信掃碼關注不迷路,第一時間獲取文章哦
   大資料 | 分散式檔案系統 HDFS
 

相關文章