天天看點

hdfs下載下傳資料源碼分析之open方法淺析

下面我們來看看open方法。

hdfs下載下傳資料源碼分析之open方法淺析

我們之前簡單分析過,這個open方法,打開這個在hdfs上的檔案的時候,首先是要通過和namenode的通信來确定這個檔案的塊在哪些datanode上面,然後通過建立與datanode的通信來獲得對應塊檔案流。

hdfs下載下傳資料源碼分析之open方法淺析

Open方法傳回的是檔案系統的資料輸入流,然後調用的是抽象的FSDataInputStream的方法,這個方法就是子類實作的方法了。下面是DistributedFileSystem的open方法。

hdfs下載下傳資料源碼分析之open方法淺析
hdfs下載下傳資料源碼分析之open方法淺析

分别代表的意思是讀了多少位元組,寫了多少位元組,有多少次讀操作,有多少次大的讀操作,有多少次寫操作。

這行代碼:Pathabsf=fixRelativePart(f),是把相對路徑改為絕對路徑,也就是将你傳進來的關于hdfs上檔案所在的路徑進行針對的變化。

然後傳回一個FileSystemLinkResolver,一個檔案系統的連接配接的解析器對象,并調用解析方法去解析這個路徑。

這個匿名内部類重寫了兩個方法,其中doCall方法是拿到流對象的關鍵。

這個匿名内部類的對象調用的resolver方法應該是回調了doCall方法,然後傳回一個流對象,我們看這個doCall方法裡面是用hdfsDataInputStream封裝了dfs.open()獲得的流對象,而這個dfs我們之前提到過是fs所持有的一個對象,它持有了一個可以和namenode進行通信的clientProtocal對象。

下面我們來看一下dfs.open()方法。

hdfs下載下傳資料源碼分析之open方法淺析

通過DFSInputStream的構造方法來構造一個對應檔案的輸入流。

然後我們來看看構造方法裡面是什麼:

hdfs下載下傳資料源碼分析之open方法淺析

DFSInputStream将dfsClient作為自己的一個成員。下面是DFSInputStream的一些成員。其中BlockReader就是去讀各個block一個對象,裡面應該是封裝了一些對datanode進行資料擷取的一些代碼。然後locatedBlocks裡面應該是存儲了block的位置資訊,通過dfsClient和namenode通信獲得。這些成員的變量指派都在openinfo()方法裡面。

hdfs下載下傳資料源碼分析之open方法淺析

下面是openinfo()方法裡面的内容。

hdfs下載下傳資料源碼分析之open方法淺析

為什麼是要取塊的位置資訊并且取最後一個block塊的長度?因為前面的塊都是按照blocksize分的block,但是最後一塊可能小于blocksize,這個時候就需要确定這個塊的長度。

hdfs下載下傳資料源碼分析之open方法淺析

拿位置資訊的時候還是通過dfsclient,可以看到是通過dfs中持有的可以和namenode通信的對象去進行block位置資訊的擷取的。

hdfs下載下傳資料源碼分析之open方法淺析

下面是callGetBlockLocations的源碼。可以看到是通過namenode的getBlockLocations方法去和namenode進行通信,進而獲得block資訊。

以下是通過rpc用戶端(namenode)代理對象調用服務端真實的實作去獲得的資訊。

hdfs下載下傳資料源碼分析之open方法淺析
hdfs下載下傳資料源碼分析之open方法淺析

其中,fileLength是檔案的總長度,underConstruction代表檔案是正常狀态,然後blocks是此檔案的block的位置,lastLocatedBlock是最後一塊的位置,isLasBlockComplete-ture是最後一個block是否完全、完整的标志。

通過這些,我們已經拿到block資訊,接下來就是dfsinputstream中blockreader指派,賦完值之後就可以去datanode拿資料了。

繼續閱讀