一、NameNode 的接口分析
1. NameNode本質
經過前面的學習,可以知道NameNode 本身就是一個java 進程。觀察RPC.getServer()方法的第一個參數,發現是this,說明NameNode 本身就是一個位於服務端的被調用對象,即NameNode 中的方法是可以被客戶端代碼調用的。根據RPC 運行原理可知,NameNode暴露給客戶端的方法是位於接口中的。
我們查看NameNode 的源碼,如圖1.1所示。
圖 1.1
可以看到NameNode 實現了ClientProtocal、DatanodeProtocal、NamenodeProtocal 等接口。
2. NameNode的接口
2.1 DFSClient 調用ClientProtocal
<1> 這個接口是供客戶端調用的。這里的客戶端不是指的我們自己寫的代碼,而是hadoop 的一個類叫做DFSClient。在DFSClient 中會調用ClientProtocal 中的方法,完成一些操作。
<2>該接口中的方法大部分是對HDFS 的操作,如create、delete、mkdirs、rename 等。
2.2 DataNode 調用DatanodeProtocal
這個接口是供DataNode 調用的。DataNode 調用該接口中的方法向NameNode 報告本節點的狀態和block 信息。NameNode 不能向DataNode 發送消息, 只能通過該接口中方法的返回值向DataNode 傳遞消息。
2.3 SecondaryNameNode 調用NamenodeProtocal
這個接口是供SecondaryNameNode 調用的。SecondaryNameNode 是專門做NameNode 中edits 文件向fsimage 合並數據的。
二、DataNode 的接口分析
按照分析NameNode 的思路,看一下DataNode 的源碼接口,如圖2.1 所示。
這里有兩個接口,分別是InterDatanodeProtocal、ClientDatanodeProtocal。這里就不展開分析了。讀者可以根據上面的思路獨立分析。
三、HDFS的數據處理過程分析
1. HDFS 的寫數據過程分析
1.1 通過FileSystem 類可以操控HDFS
那我們就從這里開始分析寫數據到HDFS 的過程。在我們向HDFS 寫文件的時候,調用的是FileSystem.create(Path path)方法,我們查看這個方法的源碼,通過跟蹤內部的重載方法,可以找到如圖3.1所示的調用。
這個方法是抽象類,沒有實現。那么我們只能向他的子類尋找實現。
1.2 查看DistributedFileSystem類的源碼
FileSystem 有個子類是DistributedFileSystem,在我們的偽分布環境下使用的就是這個類。我們可以看到DistributedFileSystem 的這個方法的實現,如圖3.2示。
圖3.2
在圖3.2中,注意第186 行的返回值FSDataOutputStream。這個返回值對象調用了自己的構造方法,構造方法的第一個參數是dfs.create()方法。
1.3 關注一下這里的dfs 對象是誰,create 方法做了什么事情。
現在進入這個方法的實現,如圖3.3 所示。
在圖3.3 中,返回值正是第866行創建的對象。
1.4 查看這個類的源碼
如圖3.4 所示。
圖3.4
在圖3.4 中, 可以看到, 這個類是DFSClient 的內部類。在類內部通過調用namenode.create()方法創建了一個輸出流。
1.5 我們再看一下namenode 對象是什么類型
如圖3.5所示。
圖3.5
在圖3.5 中,可以看到namenode 其實是ClientProtocal 接口。
1.6 那么,這個對象是什么時候創建的那?
查看該對象,如圖3.6 所示。
可以看出,namenode 對象是在DFSClient 的構造函數調用時創建的,即當DFSClient 對象存在的時候,namenode 對象已經存在了。
1.7 整個調用過程
至此,我們可以看到,使用FileSystem 對象的api 操縱HDFS,其實是通過DFSClient 對象訪問NameNode 中的方法操縱HDFS 的。這里的DFSClient 是RPC 機制的客戶端,NameNode是RPC 機制的服務端的調用對象,整個調用過程如圖3.7所示。
在整個過程中,DFSClient 是個很重要的類,從名稱就可以看出,他表示HDFS 的Client,是整個HDFS 的RPC 機制的客戶端部分。我們對HDFS 的操作,是通過FileSsytem 調用的DFSClient 里面的方法。FileSystem 是封裝了對DFSClient 的操作,提供給用戶使用的。
2. HDFS 的讀數據過程分析
2.1 對FileSystem 類分析
我們繼續對FileSystem 類分析,讀數據使用的是open(…)方法,我們可以看到源碼,如圖3.8 所示。
圖3.8
在圖3.8 中,返回的是DFSClient 類中DFSDataInputStream 類.顯而易見,這是一個內部類。
2.2 查看這個內部類的構造方法的源碼
這個內部類的構造函數,有兩個形參,第一個參數是dfs.open(…)創建的對象。我們看一下方法的源碼,如圖3.9所示。
在圖3.9的實現中,返回的是一個DFSInputStream 對象。
2.3 查看DFSInputStream這個類的構造方法源碼
該對象中含有NameNode 中的數據塊信息。我們看一下這個類的構造方法源碼,如圖3.10 所示。
圖3.10
2.4 查看獲取數據塊的信息方法源碼
在圖3.10中,這個構造方法中最重要的語句是第1836 行,打開信息,從第1842 行開始是openInfo()的源代碼,截圖顯示不全。注意第1841 行,是獲取數據塊的信息的。我們查看這一行的源代碼,如圖3.11所示。
圖3.11
從圖3.11 中可以看到,獲取數據塊信息的方法也是通過調用namenode 取得的。這里的namenode 屬性還是位於DFSClient 中的。通過前面的分析,我們已經知道,在DFSClient類中的namenode 屬性是ClientProtocal。