NameNode(NN代指)中存儲的HDFS中文件的元信息,從大的方面可以分為3個部分整個文件系統的目錄樹、文件名與blockid的映射關系、blockid所在的DN信息。其中前兩項是永久存在NN中的(image文件),第三項是DN啟動時向NN匯報生成的,這樣能夠簡化NN的存儲邏輯,並且大大減小image文件的大小。
單純看NN的存儲邏輯會比較無序,不容易理解,借助NN的啟動過程來進行分析。
NN的啟動過程:
首先執行NN中的main函數
main函數的主要工作是創建一個NN對象,並通過join方法等待其他線程運行結束。
createNameNode函數
首先獲取startOpt,就是啟動dfs時指定的參數(如-format),啟動時會對format(hadoop一開始部署完成要進行一次格式化操作,類似磁盤的格式化)和finalize(升級穩定后正式提交)。
之后創建NN的對象。具體的初始化工作是在initialize方法中,進行一堆安全檢查,然后創建FSNamesystem對象
this.namesystem = new FSNamesystem(this, conf);
之后創建RPCSever和HttpServer,具體實現可以查看Hadoop RPC部分的源代碼。
開始最重要的FSNamesystem的初始化,同樣初始化工作是在initialize方法中完成。完成的最重要的幾件事情,創建FSDirectory對象,加載image和edits文件,設置安全狀態,之后啟動幾個monitor線程。分別監控DN的心跳、租約、block的冗余備份數目。
可以看出FSNamesystem對於目錄結構的操作都是通過FSDirectory對象進行的。在FSDirectory中有一個表示系統目錄根的rootDir,rootDir是INodeDirectoryWithQuota類型,這就表明FSDirectory是作為Inode(類似Linux中的inode)與FSNamesystem之間的橋梁,FSDirectory封裝了Inode提供了對外查詢的接口。
Inode是一個抽象類,他有兩個子類INodeDirectory和INodeFile。顧名思義,INodeFile代表的是一個具體的文件,而INodeDirectory代表的是一個文件目錄。
接着看一下INodeDirectory與INodeFile之間的區別。在INodeFile中最重要的一個域是
protected BlockInfo blocks[] = null;
這就是代表每個文件所對應的blockid。而在INodeDirectory中最重要的部分是
private List<INode> children;
這就是一個文件目錄中的目錄項的集合,也就是目錄樹。
上面我們知道了目錄樹和blockid的存儲結構,接着來看在image文件和edits文件時候是否按照這樣的結構進行組織。