1. 程式人生 > >hadoop:hdfs架構及原理

hadoop:hdfs架構及原理

HDFS簡介

HDFS:Hadoop Distributed File System(hadoop分散式檔案系統) 分散式,感覺好厲害的樣子啊,有網路檔案系統,有本地檔案系統,現在又多了一個分散式的檔案系統。之所以是要分散式,是資料要放到多個主機上面去。放的東西在叢集中,就是分散式啦! 想要了解這個東東,先找一張原理圖瞅瞅。

HDFS整體處理流程圖 看不懂沒關係,繼續往下瞅就是了。

HDFS 1.0

每個一學習的模組要搞懂一個點內容,學完這個就需要對下面這些名詞非常的瞭解。 Namenode Datanode 冷備份(sendarynamenode)

Namenode

namenode又稱為名稱節點,是負責管理分散式檔案系統的名稱空間(Namespace),儲存了兩個核心的資料結構,即FsImage和EditLog

。 你可以把它理解成大管家,它不負責儲存具體的資料。

  • FsImage用於維護檔案系統樹以及檔案樹中所有的檔案和資料夾的元資料
  • 操作日誌檔案EditLog中記錄了所有針對檔案的建立、刪除、重新命名等操作 注意,這個兩個都是檔案,也會載入解析到記憶體中。

為啥會拆成兩個呢? 主要是因為fsimage這個檔案會很大的,多了之後就不好操作了,就拆分成兩個。把後續增量的修改放到EditLog中, 一個FsImage和一個Editlog 進行合併會得到一個新的FsImage.

因為它是系統的大管家,如果這個玩意壞了,丟失了怎麼辦。就相當於你係統的引導區壞了。那就玩完了。整個檔案系統就崩潰了。 所以,這個重要的東西,需要備份

。這個時候就產生了一個叫sendaryNamenode的節點用來做備份,它會定期的和namenode就行通訊來完成整個的備份操作。具體的操作如下:

HDFS HA 原理圖

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就變小了

除了這個自帶的備份操作,還需要進行人工的備份,把一份fsimage到多個地方進行備份,萬一namenode的節點壞了呢。

DataNode

datanode資料節點,用來具體的儲存檔案,維護了blockId 與 datanode本地檔案的對映。 需要不斷的與namenode節點通訊,來告知其自己的資訊,方便nameode來管控整個系統。

這裡還提到一個的概念,就想linux本地檔案系統中也有塊的概念一樣,這裡也有塊的概念。這裡的塊會預設是128m 每個塊都會預設儲存三份。

HDFS 2.0

有問題,就得改。1.0上有很多的毛病,為了修復這些問題才出了2.0 * 單點故障問題 * 不可以水平擴充套件(是否可以通過縱向擴充套件來解決?) * 系統整體效能受限於單個名稱節點的吞吐量 * 單個名稱節點難以提供不同程式之間的隔離性 * HDFS HA是熱備份,提供高可用性,但是無法解決可擴充套件性、系統性能和隔離性

解決上面這些問題所使用的手段就是 熱備份 federation

熱備份 (HDFS HA)

  • HDFS HA(High Availability)是為了解決單點故障問題
  • HA叢集設定兩個名稱節點,“活躍(Active)”和“待命(Standby)”
  • 兩種名稱節點的狀態同步,可以藉助於一個共享儲存系統來實現
  • 一旦活躍名稱節點出現故障,就可以立即切換到待命名稱節點
  • Zookeeper確保一個名稱節點在對外服務
  • 名稱節點維護對映資訊,資料節點同時向兩個名稱節點彙報資訊

HDFS HA 原理圖

Federation(大概翻譯成聯盟)

多個名稱空間。為了處理一個namenode的侷限性,搞了幾個namanode大家一起來管理。就像程式設計中的名稱空間一樣

HDFS Federation 原理圖

  • 在HDFS Federation中,設計了多個相互獨立的名稱節點,使得HDFS的命名服務能夠水平擴充套件,這些名稱節點分別進行各自名稱空間和塊的管理,相互之間是聯盟(Federation)關係,不需要彼此協調。並且向後相容
  • HDFS Federation中,所有名稱節點會共享底層的資料節點儲存資源,資料節點向所有名稱節點彙報
  • 屬於同一個名稱空間的塊構成一個“塊池

HDFS Federation設計可解決單名稱節點存在的以下幾個問題: 1. HDFS叢集擴充套件性。多個名稱節點各自分管一部分目錄,使得一個叢集可以擴充套件到更多節點,不再像HDFS1.0中那樣由於記憶體的限制制約檔案儲存數目 2. 效能更高效。多個名稱節點管理不同的資料,且同時對外提供服務,將為使用者提供更高的讀寫吞吐率 3. 良好的隔離性。使用者可根據需要將不同業務資料交由不同名稱節點管理,這樣不同業務之間影響很小

===============================================================================================

1、HDFS 是做什麼的

  HDFS(Hadoop Distributed File System)是Hadoop專案的核心子專案,是分散式計算中資料儲存管理的基礎,是基於流資料模式訪問和處理超大檔案的需求而開發的,可以運行於廉價的商用伺服器上。它所具有的高容錯、高可靠性、高可擴充套件性、高獲得性、高吞吐率等特徵為海量資料提供了不怕故障的儲存,為超大資料集(Large Data Set)的應用處理帶來了很多便利。

2、HDFS 從何而來

  HDFS 源於 Google 在2003年10月份發表的GFS(Google File System) 論文。 它其實就是 GFS 的一個克隆版本

3、為什麼選擇 HDFS 儲存資料

   之所以選擇 HDFS 儲存資料,因為 HDFS 具有以下優點:

  1、高容錯性

  • 資料自動儲存多個副本。它通過增加副本的形式,提高容錯性。

  • 某一個副本丟失以後,它可以自動恢復,這是由 HDFS 內部機制實現的,我們不必關心。

  2、適合批處理

  • 它是通過移動計算而不是移動資料。

  • 它會把資料位置暴露給計算框架。

  3、適合大資料處理

  • 處理資料達到 GB、TB、甚至PB級別的資料

  • 能夠處理百萬規模以上的檔案數量,數量相當之大。

  • 能夠處理10K節點的規模。

  4、流式檔案訪問

  • 一次寫入,多次讀取。檔案一旦寫入不能修改,只能追加。

  • 它能保證資料的一致性。

  5、可構建在廉價機器上

  • 它通過多副本機制,提高可靠性。

  • 它提供了容錯和恢復機制。比如某一個副本丟失,可以通過其它副本來恢復。

  當然 HDFS 也有它的劣勢,並不適合所有的場合:

  1、低延時資料訪問

  • 比如毫秒級的來儲存資料,這是不行的,它做不到。

  • 它適合高吞吐率的場景,就是在某一時間內寫入大量的資料。但是它在低延時的情況下是不行的,比如毫秒級以內讀取資料,這樣它是很難做到的。

  2、小檔案儲存

  • 儲存大量小檔案(這裡的小檔案是指小於HDFS系統的Block大小的檔案(預設64M))的話,它會佔用 NameNode大量的記憶體來儲存檔案、目錄和塊資訊。這樣是不可取的,因為NameNode的記憶體總是有限的。

  • 小檔案儲存的尋道時間會超過讀取時間,它違反了HDFS的設計目標。

  3、併發寫入、檔案隨機修改

  • 一個檔案只能有一個寫,不允許多個執行緒同時寫。

  • 僅支援資料 append(追加),不支援檔案的隨機修改。

4、HDFS 如何儲存資料

  

                  HDFS的架構圖

  HDFS 採用Master/Slave的架構來儲存資料,這種架構主要由四個部分組成,分別為HDFS Client、NameNode、DataNode和Secondary NameNode。下面我們分別介紹這四個組成部分   

  1、Client:就是客戶端。

  • 檔案切分。檔案上傳 HDFS 的時候,Client 將檔案切分成 一個一個的Block,然後進行儲存。
  • 與 NameNode 互動,獲取檔案的位置資訊。
  • 與 DataNode 互動,讀取或者寫入資料。
  • Client 提供一些命令來管理 HDFS,比如啟動或者關閉HDFS。
  • Client 可以通過一些命令來訪問 HDFS。

  2、NameNode:就是 master,它是一個主管、管理者。

  • 管理 HDFS 的名稱空間
  • 管理資料塊(Block)對映資訊
  • 配置副本策略
  • 處理客戶端讀寫請求。

  3、DataNode:就是Slave。NameNode 下達命令,DataNode 執行實際的操作。

  • 儲存實際的資料塊。
  • 執行資料塊的讀/寫操作。

  4、Secondary NameNode:並非 NameNode 的熱備。當NameNode 掛掉的時候,它並不能馬上替換 NameNode 並提供服務。

  • 輔助 NameNode,分擔其工作量。
  • 定期合併 fsimage和fsedits,並推送給NameNode。
  • 在緊急情況下,可輔助恢復 NameNode。

5、HDFS 如何讀取檔案

HDFS的檔案讀取原理,主要包括以下幾個步驟:

  • 首先呼叫FileSystem物件的open方法,其實獲取的是一個DistributedFileSystem的例項。
  • DistributedFileSystem通過RPC(遠端過程呼叫)獲得檔案的第一批block的locations,同一block按照重複數會返回多個locations,這些locations按照hadoop拓撲結構排序,距離客戶端近的排在前面。
  • 前兩步會返回一個FSDataInputStream物件,該物件會被封裝成 DFSInputStream物件,DFSInputStream可以方便的管理datanode和namenode資料流。客戶端呼叫read方法,DFSInputStream就會找出離客戶端最近的datanode並連線datanode。
  • 資料從datanode源源不斷的流向客戶端。
  • 如果第一個block塊的資料讀完了,就會關閉指向第一個block塊的datanode連線,接著讀取下一個block塊。這些操作對客戶端來說是透明的,從客戶端的角度來看只是讀一個持續不斷的流。
  • 如果第一批block都讀完了,DFSInputStream就會去namenode拿下一批blocks的location,然後繼續讀,如果所有的block塊都讀完,這時就會關閉掉所有的流。

6、HDFS 如何寫入檔案

HDFS的檔案寫入原理,主要包括以下幾個步驟:

  • 客戶端通過呼叫 DistributedFileSystem 的create方法,建立一個新的檔案。
  • DistributedFileSystem 通過 RPC(遠端過程呼叫)呼叫 NameNode,去建立一個沒有blocks關聯的新檔案。建立前,NameNode 會做各種校驗,比如檔案是否存在,客戶端有無許可權去建立等。如果校驗通過,NameNode 就會記錄下新檔案,否則就會丟擲IO異常。
  • 前兩步結束後會返回 FSDataOutputStream 的物件,和讀檔案的時候相似,FSDataOutputStream 被封裝成 DFSOutputStream,DFSOutputStream 可以協調 NameNode和 DataNode。客戶端開始寫資料到DFSOutputStream,DFSOutputStream會把資料切成一個個小packet,然後排成佇列 data queue。
  • DataStreamer 會去處理接受 data queue,它先問詢 NameNode 這個新的 block 最適合儲存的在哪幾個DataNode裡,比如重複數是3,那麼就找到3個最適合的 DataNode,把它們排成一個 pipeline。DataStreamer 把 packet 按佇列輸出到管道的第一個 DataNode 中,第一個 DataNode又把 packet 輸出到第二個 DataNode 中,以此類推。
  • DFSOutputStream 還有一個佇列叫 ack queue,也是由 packet 組成,等待DataNode的收到響應,當pipeline中的所有DataNode都表示已經收到的時候,這時akc queue才會把對應的packet包移除掉。
  • 客戶端完成寫資料後,呼叫close方法關閉寫入流。
  • DataStreamer 把剩餘的包都刷到 pipeline 裡,然後等待 ack 資訊,收到最後一個 ack 後,通知 DataNode 把檔案標示為已完成。

7、HDFS 副本存放策略

namenode如何選擇在哪個datanode 儲存副本(replication)?

這裡需要對可靠性、寫入頻寬和讀取頻寬進行權衡。Hadoop對datanode儲存副本有自己的副本策略,在其發展過程中一共有兩個版本的副本策略,分別如下所示

8、hadoop2.x新特性

  • 引入了NameNode Federation,解決了橫向記憶體擴充套件
  • 引入了Namenode HA,解決了namenode單點故障
  • 引入了YARN,負責資源管理和排程
  • 增加了ResourceManager HA解決了ResourceManager單點故障

  1、NameNode Federation

    架構如下圖

    

  • 存在多個NameNode,每個NameNode分管一部分目錄
  • NameNode共用DataNode

  這樣做的好處就是當NN記憶體受限時,能擴充套件記憶體,解決記憶體擴充套件問題,而且每個NN獨立工作相互不受影響,比如其中一個NN掛掉啦,它不會影響其他NN提供服務,但我們需要注意的是,雖然有多個NN,分管不同的目錄,但是對於特定的NN,依然存在單點故障,因為沒有它沒有熱備,解決單點故障使用NameNode HA

2、NameNode HA

    解決方案:

  • 基於NFS共享儲存解決方案
  • 基於Qurom Journal Manager(QJM)解決方案

    1、基於NFS方案

      Active NN與Standby NN通過NFS實現共享資料,但如果Active NN與NFS之間或Standby NN與NFS之間,其中一處有網路故障的話,那就會造成資料同步問題

    2、基於QJM方案

       架構如下圖

       

      Active NN、Standby NN有主備之分,NN Active是主的,NN Standby備用的

      叢集啟動之後,一個namenode是active狀態,來處理client與datanode之間的請求,並把相應的日誌檔案寫到本地中或JN中;

      Active NN與Standby NN之間是通過一組JN共享資料(JN一般為奇數個,ZK一般也為奇數個),Active NN會把日誌檔案、映象檔案寫到JN中去,只要JN中有一半寫成功,那就表明Active NN向JN中寫成功啦,Standby NN就開始從JN中讀取資料,來實現與Active NN資料同步,這種方式支援容錯,因為Standby NN在啟動的時候,會載入映象檔案(fsimage)並週期性的從JN中獲取日誌檔案來保持與Active NN同步

      為了實現Standby NN在Active NN掛掉之後,能迅速的再提供服務,需要DN不僅需要向Active NN彙報,同時還要向Standby NN彙報,這樣就使得Standby NN能儲存資料塊在DN上的位置資訊,因為在NameNode在啟動過程中最費時工作,就是處理所有DN上的資料塊的資訊

      為了實現Active NN高熱備,增加了FailoverController和ZK,FailoverController通過Heartbeat的方式與ZK通訊,通過ZK來選舉,一旦Active NN掛掉,就選取另一個FailoverController作為active狀態,然後FailoverController通過rpc,讓standby NN轉變為Active NN

      FailoverController一方面監控NN的狀態資訊,一方面還向ZK定時傳送心跳,使自己被選舉。當自己被選為主(Active)的時候,就會通過rpc使相應NN轉變Active狀態

    3、結合HDFS2的新特性,在實際生成環境中部署圖

  

上圖有12個DN,有4個NN,NN-1與NN-2是主備關係,它們管理/share目錄;

NN-3與NN-4是主備關係,它們管理/user目錄。