複製鏈接
請複製以下鏈接發送給好友

NameNode

鎖定
NameNode,管理文件系統的命名空間。它維護着文件系統樹及整棵樹內所有的文件和目錄。這些信息以兩個文件形式永久保存在本地磁盤上:命名空間鏡像文件和編輯日誌文件。NameNode也記錄着每個文件中各個塊所在的數據節點信息,但它並不永久保存塊的位置信息,因為這些信息在系統啓動時由數據節點重建。
外文名
NameNode
定    義
管理文件系統的命名空間
功    能
維護文件系統樹及整棵樹內所有的文件和目錄

NameNode節點介紹

HDFS集羣有兩類節點,並以管理者-工作者模式運行,即一個NameNode(管理者)和多個DataNode(工作者)。一個HDFS cluster包含一個NameNode和若干的DataNode,NameNode(以下簡稱nn)是master,主要負責管理hdfs文件系統,具體地包括namespace管理(其實就是目錄結構),block管理(其中包括 filename➝block,block➝datanode list的對應關係)。nn提供的是始終被動接收服務的server,主要有四類協議接口:ClientDatanodeProtocol接口、ClientProtocol接口、DatanodeProtocol接口、NamenodeProtocol接口。DataNode(以下簡稱dn)主要是用來存儲數據文件,HDFS將一個文件分割成一個個的block,這些block可能存儲在一個DataNode上或者是多個DataNode上。dn負責實際的底層的文件的讀寫,如果客户端client程序發起了讀hdfs上的文件的命令,那麼首先將這些文件分成block,然後nn將告知client這些block數據是存儲在哪些dn上的,之後,client將直接和dn交互。
還有一個重要的節點:Secondary NameNode,該部分主要是定時對NameNode進行數據snapshots進行備份,這樣儘量降低NameNode崩潰之後,導致數據的丟失,其實所作的工作就是從nn獲得fsimage和edits把二者重新合併然後發給nn,這樣,既能減輕nn的負擔又能保險地備份。

NameNode數據結構

NameNode NameNode
FSdirectory
FSDirectory存儲整個文件系統的目錄狀態,對整個目錄結構的管理通過調用FSImage和FSEditLog的方法從namenode本地磁盤讀取元數據信息和向本地磁盤寫入元數據信息,並登記對目錄結構所作的修改到日誌文件。另外,FSDirectory保存了文件名和數據塊的映射關係。INode是對文件系統目錄結構中一個節點的抽象
INodeFile和INodeDirectory均繼承自INode類,分別表示文件節點和目錄節點。
INodeFile類中最重要的數據結構是BlockInfo blocks[ ],它記錄了一個文件所包含的所有Block,成員方法的操作大都與Block相關
INodefileUnderConstruction表示正在都建的文件
INodeDirectory的關鍵數據結構是List<INode> children記錄了目錄下所有的子節點信息
INodeDirectoryWithQuota表示有配額限制的目錄,根目錄就是這種類型。
FSimage
把文件和目錄的元數據信息持久化地存儲到fsimage文件中,每次啓動時從中將元數據加載到內存中構建目錄結構樹,之後的操作記錄在edits log中
定期將edits與fsimage合併刷到fsimage中
loadFSImage(File curFile)用於從fsimage中讀入Namenode持久化的信息。fsimage中保存的元數據信息格式如下,hdfs加載和寫入時都按照該格式進行
fsimage是一個二進制文件,當中記錄了HDFS中所有文件和目錄的元數據信息,這是網上流傳的一張經典圖。
FSimage FSimage
imageVersion(int)——image版本號
namespaceID(int)——命名空間ID,在namenode的生命期內保持不變,datanode註冊時
返回作為其registrationID,每次和namenode通信時都要檢查,不認識的namespaceID拒絕連接.
numFiles(16版以後long型)記錄文件系統中的文件數
genstamp(long)生成image時間戳
下面是numFiles個文件(目錄)信息:
path(String)文件或目錄路徑
replication(int)副本數,會調用FSEditLog.adjustReplication(replication);調整,目錄的為0
mtime(long)修改時間
atime(long)訪問時間
blockSize(long)塊大小,目錄是0
NumBlocks(int)文件包含的塊數(imageVersion 9以後的版本numBlocks>=0時表示文件,之前的版本>0時表示文件),目錄的為-1,saveINode2Image方法中可以看到
如果是文件,下面是NumBlocks個block的相關信息:
blockId(long):該文件的block的blockid,
numBytes(long):該block的大小
generationStamp(long):該block的時間戳
如果是目錄,讀入quota信息:
nsQuota(long)命名空間大小配額,默認-1
dsQuota(long)磁盤空間配額,默認-1
下面是權限相關
username(String)文件或目錄的所屬用户名
groupname(String)組名
permission(short)權限
如果前面的path.length==0,表示根目錄,設置根目錄的配額,修改時間,訪問時間和權限信息。
將這些信息讀入內存之後,構造一個文件目錄結構樹,將表示文件或目錄的節點填入到結構中。
然後是加載datanode信息(新版已取消該項)
再之後是加載FilesUnderConstruction.
BlocksMap
block➝datanode的信息沒有持久化存儲,而是namenode通過datanode的blockreport獲取block➝datanode list
BlocksMap負責維護了三種信息:
block➝datanode list
block➝INodeFile
datanode➝blocks
這要歸功於一個很牛逼的結構:Object[ ] triplets
BlocksMap BlocksMap
他是一個三元組,每個block有幾個副本,就有幾個三元組。三元組的第一個元素表示該block所屬的Datanode,類型是DatanodeDescriptor,通過它獲得
block➝datanode list
第二/三個元素表示該block所在Datanode上的前/後一個block(前驅和後繼),類型是BlockInfo,通過它獲得datanode➝blocks
藉助這個三元組可以找到一個block所屬的所有datanode,也可以通過三元組的後兩個元素信息找到一個datanode上所有的block。
上面這兩個結構介紹之後,nn需要的namespace信息和block信息基本就全了。在nn加載fsimage完成之後,BlocksMap中只有每個block到其所屬的datanodes list的對應關係信息還沒建立。然後通過dn的blockReport來收集構建。當所有的dn彙報給nn的blockReport處理完畢後,BlocksMap整個結構也就構建完成了。