HDFS讀書筆記-瞭解NameNode(二)

朋友寫的【HDFS系列】,覺得挺好。原文地址,點我

     上篇文章中我們着重介紹了HDFS的基本架構和讀寫流程,本章主要來認識HDFS的NameNode,
     簡單來講,NameNode就是HDFS的大腦,任何客戶端或者DataNode的數據遷移、目錄操作都是由NameNode來完成的。
     再瞭解了NameNode會幹什麼事情之後,最好深入的辦法就是來看NameNode有哪些重要的數據結構,每個數據結構都幹什麼事情。

 

     我們提到NameNode主要是維護文件在哪裏這個映射關係。故而主要包含的內容是:
     1、fileName和目錄block的關係。
     2、block到mist(機器列表)的關係。
     fileName到block的關係是fsimage(類似鏡像文件)寫入到本地,每次啓動的時候進行加載。block到mlist的的關係則是通過HDFS啓動後,DataNode向NameNode報告心跳實現。爲什麼這樣設計的原因:
     1、文件和目錄block的關係存在的時候不會發生變化。
     2、block和mlist的關係會因爲均衡數據遷移,機器故障數據遷移發生變化。
     3、架構考慮點。
    NameNode只有三種交互。
     1、client訪問NameNode獲取相關DataNode信息。
     2、DataNode心跳彙報當前block情況。
     3、SecondaryNameNode做checkpoint交互。
先來看類圖:
HDFS讀書筆記-瞭解NameNode(二)

FSNameSystem
    在NameNode中,基本上重要的創建,維護,同步,更新都操作都是通過FSNameSystem來完成的。各種關鍵的數據結構也是在FSNameSystem中維護的。可以這樣說基本上做的所有操作都是通過和FSNameSystem打交道來完成的。

FSDirectory
    顧名思義,該類是用來維護所有以文件路徑的。這個類維護着HDFS中所有的目錄信息,並且會被持久化到NameNode本地作爲FSImage(非常緊湊的二進制文件)存儲起來。FSImage的相關操作也是通過FSDirectory完成的,HDFS的各種操作,會記錄到EditLog中(EditLog也是通過FSDriectory維護),週期性的把FSImage和EditLog合併起來就是當前所有的目錄信息。
HDFS所有的目錄信息是通過樹的方式來維護的。(想象一下普通的電腦上的文件不都是以樹的方式維護的嗎),在HDFS中所有文件的抽象是INode,目錄則是INodeDirectory,文件則是INodeFile。

FSImage
    從上一部分我們已經瞭解到了,FSImage就是文件目錄元數據的某個時間段的鏡像文件。每次啓動後所有文件目錄操作都會通過FSDriectory記錄到EditLog,這帶來一個問題,啓動的時間越長EditLog中的內容會更多,下次再做合併的時候(這個合併我們稱爲checkpoint),會隨着EidtLog文件的大小增加合併的時間,HDFS針對這個問題設置了兩種機制進行條件合併,例如配置EditLog達到多大做一次合併,或者離上次合併過了多久做一次合併。 但是如果NameNode合併文件佔用過多的資源,可能會引發其他的問題。那麼如何來避免這樣一個問題呢?後續我們會介紹,如何用
SecondaryNameNode來避免這個問題。
FSImage文件格式如下:

HDFS讀書筆記-瞭解NameNode(二)
  

當namenode重啓加載fsimage時,就是按照如下格式協議從文件流中加載元數據信息。從fsimag的存儲格式可以看出,fsimage保存有如下信息:

一、加載Img頭信息,如下:

          1、 imgVersion(int):當前image的版本信息

          2、namespaceID(int):用來確保別的HDFS instance中的datanode不會誤連上當前NN。

          3、numFiles(long):整個文件系統中包含有多少文件和目錄

          4、genStamp(long):生成該image時的時間戳信息。

二 、如果加載目錄,包含以下信息:

          1、path(String):該目錄的路徑,如”/user/build/build-index”

          2、replications(short):副本數(目錄雖然沒有副本,但這裏記錄的目錄副本數也爲3)

          3、mtime(long):該目錄的修改時間的時間戳信息

          4、atime(long):該目錄的訪問時間的時間戳信息

          5、blocksize(long):目錄的blocksize都爲0

          6、numBlocks(int):實際有多少個文件塊,目錄的該值都爲-1,表示該item爲目錄

          7、nsQuota(long):namespace Quota值,若沒加Quota限制則爲-1

          8、dsQuota(long):disk Quota值,若沒加限制則也爲-1

          9、username(String):該目錄的所屬用戶名

          10、group(String):該目錄的所屬組

          11、permission(short):該目錄的permission信息,如644等,有一個short來記錄。

三、如果加載文件,則還會額外包含如下信息:

          1、blockid(long):屬於該文件的block的blockid,

          2、numBytes(long):該block的大小

          3、genStamp(long):該block的時間戳

    當該文件對應的numBlocks數不爲1,而是大於1時,表示該文件對應有多個block信息,此時緊接在該fsimage之後的就會有多個blockid,numBytes和genStamp信息。

    因此,在namenode啓動時,就需要對fsimage按照如下格式進行順序的加載,以將fsimage中記錄的HDFS元數據信息加載到內存中。
BlocksMap
    最初我們提到過FSImage中沒有block到機器列表的映射關係的原因。每一個DataNode啓動的時候會通過BlockReport將當前機器所有block信息彙報給NameNode。彙報的相關信息就是維護在BlockMaps中的,
    BlocksMap結構如下:
HDFS讀書筆記-瞭解NameNode(二)


    我們前面提到,FSImage中維護的是文件和block的關係,那麼block和機器的關係便是從BlocksMap中獲取的。
    BlocksMap維護了三種關係:
          1、file-blcoks
           2、block-datanodelist
           3、datanode-blocks
從上圖中我們也可以看到,BlocksMap中的BlockInfo中維護了包括:
          1、blockid,塊ID。
          2、塊大小。
          3、塊的修改時間戳。
          4、塊對應的文件。
          5、塊對應的機器列表信息。 
DataNode列表
    在上圖中已經看到,每一個BlockInfo上都有一個DN1,DN2,DN3其實就是一個block在三臺機器上的備份。每一個DataNode對應的是一個Object[]的三元數組,prev表示當前block在該機器上的上一個block,next表示當前block在該機器上的下一個數組。目的很簡單,查詢一個DataNode上的所有BlockList需求非常少。這樣做一來可以節省大量的內存(我們說過,內存會成爲NameNode的瓶頸哦),二來直接根據next的指向就可以獲取一個DN上的所有blocklist數據。
CorruptReplicationMap 
    簡單來理解,在DN上有問題的block(磁盤壞,校驗不對)都會在這裏,下一次DN做心跳的時候有問題的block會返回給DN並刪除。
UnderReplicationMap
    默認的block副本數目是3,沒有達到這個數目(磁盤壞了,DN掛了)的都會在這裏,並且離的越遠,數據遷移優先級會越高。
PeddingReplicationMap
    block壞了,咱要做數據拷貝吧,在遷移中的5分鐘沒有成功的就認爲失敗,則添加到neededReplicationBlocks中,以便下次再做數據拷貝。


    本篇文章,我們簡單的介紹了NameNode的基本數據結構,但是對於NameNode的單點問題,checkpoint的問題,包括文中提到的SecondaryNameNode等並沒有做詳細的介紹。
下一篇:

HDFS讀書筆記-如何讓NameNode高可用(三)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章