Hadoop 2.6.5 FileSystem和Configuration兩個對象的探究

Hadoop 2.6.5 FileSystem和Configuration兩個對象的探究html

 

版權聲明:本文爲yunshuxueyuan原創文章,如需轉載,請標明出處。【http://www.cnblogs.com/sxt-zkys/】
QQ技術交流羣:299142667node

 

 (結論)緩存

經過尚學堂旗下雲數學院大數據周老師的講解能夠獲得如下結論:用相同的地址獲取的FileSystem對象是同一個; 第一次獲取對象後會有相似於緩存的機制, 即便改變了configuration參數, 只要地址沒有發生變化, 獲取的FileSystem 對象不會改變.服務器

[從bug開始]oop

在測試上傳數據到HDFS集羣時, 想更改blocksize的大小來測試小文件分塊的狀況, 使用了以下代碼(爲了便於閱讀, 刪去了JUNIT的註解):測試

 

Configuration conf = null; FileSystem fs = null; 

 //初始化fs對象 

 conf = new Configuration(true); 

 fs = FileSystem.get(conf);

 //更改blocksize大小 

 conf.set("dfs.blocksize", "1048576"); 

 fs = FileSystem.get(conf); 

 //上傳文件

 Path srcPath = new Path("d:\\testup.txt");

 Path dstPath = new Path("/user/root/test03.txt");

 fs.copyFromLocalFile(srcPath, dstPath);

 

 

從結果來看, 生成的文件大小並無改變:大數據

 

那咱們從新定義一個FileSystem來嘗試一下:spa

因而接着上段代碼, 有了以下代碼:debug

 

//初始化fs2對象 

 Configuration conf2 = new Configuration(true);

 conf2.set("dfs.blocksize", "1048576"); 

 FileSystem fs2 = FileSystem.get(conf2); 

 //上傳文件 

 Path dstPath2 = new Path("/user/root/test04.txt");

 fs2.copyFromLocalFile(srcPath, dstPath2);

 

然而結果並不樂觀:code

此時其餘的小夥伴@2元店主 已經完成了測試, 上傳文件成功, 而且設置分塊大小也沒有問題, 他的代碼以下:

//初始化fs對象 

 Path srcPath = new Path("d:\\testup.txt"); 

 Path dstPath = new Path("/user/root/test07.txt"); 

Configuration confnew = new Configuration(true);

 confnew.set("dfs.blocksize", "1048576"); 

 FileSystem fsnew = FileSystem.get(confnew); 

 //上傳文件 

 fsnew.copyFromLocalFile(srcPath, dstPath);

 

對比能夠發現, 其中的核心代碼並無什麼差別, 那麼是什麼問題引發的blocksize改變不成功呢?

通過尚學堂同班同窗的大力協助, 咱們肯定了差別點, 在個人測試代碼中, 先從配置(conf)生成過了一次FileSystem對象, 更改的blocksize後再次生成FileSystem對象. 多是這個過程出現了問題.

若是是這個問題, 那麼個人第二次測試的代碼也失效根本說不過去, 由於我是全新的對象, 與以前對象並沒有關聯.

到了這裏, 咱們對bug的產生有了一些思路.

 

[進一步測試]

爲了明確具體的問題所在, 有了以下代碼:

由於下面的代碼長得我都不想仔細讀, 因此在這裏說一下大概思路:

測試代碼兩兩一組, 每組獲取FileSystem對象用的地址是相同的;

第一組讀取本地配置文件, 先生成FileSystem對象後更改blocksize配置, 再次生成FileSystem對象

第二組不讀取本地配置文件, 地址是node01, 先更改blocksize爲1M, 生成FileSystem對象, 改變blocksize爲128M, 再次生成FileSystem對象

第三組不讀取本地配置文件, 地址是192.168的具體地址, 先更改blocksize爲128M, 生成FileSystem對象, 改變blocksize爲1M, 再次生成FileSystem對象

最後, 輸出全部的FileSystem對象toString方法

 

//第一組 

 Configuration confa = new Configuration(true); 

FileSystem fsa = FileSystem.get(confa);

confa.set("dfs.blocksize", "1048576"); 

fsa = FileSystem.get(confa); 

System.out.println(fsa.getDefaultBlockSize()); 

Configuration confb = new Configuration(true); 

confb.set("dfs.blocksize", "1048576"); 

FileSystem fsb = FileSystem.get(confb); 

 System.out.println(fsb.getDefaultBlockSize());

 

//第二組

 Configuration confc = new Configuration(false); 

confc.set("fs.defaultFS", "hdfs://node01:8020"); 

 confc.set("dfs.blocksize", "1048576");

 FileSystem fsc = FileSystem.get(confc); 

 System.out.println(fsc.getDefaultBlockSize());

 Configuration confd = new Configuration(false);

 confd.set("fs.defaultFS", "hdfs://node01:8020"); 

 confd.set("dfs.blocksize", "134217728"); 

FileSystem fsd = FileSystem.get(confd);

 System.out.println(fsd.getDefaultBlockSize());

 

//第三組 

 Configuration confe = new Configuration(false); 

confe.set("fs.defaultFS", "hdfs://192.168.109.51:8020"); 

 confe.set("dfs.blocksize", "134217728"); 

FileSystem fse = FileSystem.get(confe); 

 System.out.println(fse.getDefaultBlockSize()); 

 Configuration conff = new Configuration(false);

 conff.set("fs.defaultFS", "hdfs://192.168.109.51:8020");

 conff.set("dfs.blocksize", "1048576");

 FileSystem fsf = FileSystem.get(conff);

 System.out.println(fsf.getDefaultBlockSize());

 

 

//輸出 

 

System.out.println(fsa); 

 System.out.println(fsb); 

 System.out.println(fsc); 

 System.out.println(fsd); 

 System.out.println(fse); 

 System.out.println(fsf);

 

此次測試得到了預期的結果:

 

134217728 

134217728 

1048576

1048576

134217728 

134217728 

DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1193042798_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1193042798_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1041604824_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1041604824_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1719045568_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1719045568_1, ugi=root (auth:SIMPLE)]]

 

 

FileSystem對象的id能夠看出, 相同地址獲取的對象確實是同一對象, 至此, bug的產生已經能夠解釋的清楚了

 

[解決bug後的思考]

從最後的測試的結果能夠看出, 源碼的實現中有緩存處理, 當已經鏈接過一次以後, 再次獲取FileSystem對象時並不會讀取configuration中的參數, 只是根據地址與對象, 從相似於kv對的關係返回真實的FileSystem對象. 

 

debug模式運行代碼會發現, 第一次根據配置生成FileSystem對象時有大約10s的延時, 這應該是服務器通信形成的, 由於服務器通信的時間成本過高, 因此纔會採起這種緩存的方式返回對象.

 

通常使用中並不會對配置參數作調整, 所以這種實現方式不能說有問題, 可是若是須要臨時更改配置參數時, 則需對這個問題當心一些.

 

最後, 感謝 尚學堂周老師,在此次解決bug時提供的幫助與思路.

 

如需下載代碼和hadoop安裝文件下載:

http://www.bjsxt.com/2015/down_0526/41.html

相關文章
相關標籤/搜索