記錄一個Hadoop Configuration易產生的誤用
原文連結:http://dongxicheng.org/mapreduce-nextgen/hadoop-configuration-usage/
Hadoop提供了一個擴充套件性極好的key/value格式的配置管理器Configuration,你可以設定任意的屬性名,並通過Configuration物件獲取對應的屬性值。
Hadoop Common中定義了Configuration的基本實現,其他模組/系統,比如MapReduce,HDFS,YARN,HBase等,均在這個基礎實現基礎上,實現了自己的Configuration,比如MapReduce中叫JobConf,HDFS中叫HdfsConfiguration,YARN中交YarnConfiguration,HBase中叫HBaseConfiguration,這些Configuration實現非常簡單,他們繼承基類Configuration,然後載入自己的xml配置檔案,通常這些配置檔案成對出現,比如MapReduce分別為mapred-default.xml和mapred-site.xml,HDFS分別為hdfs-default.xml,hdfs-site.xml。
Configuraion允許你通過兩種方式設定key/value格式的屬性,一種是通過set方法,另一種通過addResouce(String name),將一個xml檔案載入到Configuration中。本文重點談一下第二種使用過程中可能遇到的問題。大家請看下面一段程式碼:
1 2 3 4 |
|
該程式最後會輸出200,而不是xicheng.xml中設定的300,為什麼呢?因為當一個配置屬性是使用者通過set方法設定的時,該屬性的來源將被標註為“programatically”,這樣的屬性是不能被addResource方法覆蓋的,必須通過set方法覆蓋或修改。在addResource實現中,首先會用指定的xml檔案覆蓋包含的所有屬性,之後再還原“programmatically”來源的那些屬性。
那麼問題來了,假設你的客戶端core-site.xml(建立Configuration物件時,該配置檔案會被預設載入)中配置了屬性xicheng.dong.age為300,而staging-hbase-site.xml中將其設成了400,那麼接下來一段程式碼會列印什麼結果呢?
1 2 3 |
|
最後結果將是300,而不是400。
如果你把第一句:
1 |
|
改為
1 |
|
結果就是你預想的400,為什麼呢?
這是由於HBaseConfiguration.create這個函式造成的,如果帶了Configuration引數,則實現如下:
1 2 3 4 5 6 7 8 9 10 11 |
|
返回的Configuration中所有屬性均是通過set方法設定的,這些所有屬性均變成了” programatically”來源,之後便不可以被addResource覆蓋了。
如果不帶Configuration引數,HBaseConfiguration.create實現如下:
1 2 3 4 |
|
所有屬性的來源均為某個xml檔案,比如”core-site.xml”,“hdfs-site.xml”等,這類屬性是可以被addResource覆蓋的。
總結
使用Hadoop Configuration進行程式設計的時候,當使用addResource載入xml中配置檔案時,一些屬性有可能不會被覆蓋掉(注意,final的屬性總是不可以覆蓋),此時一定要注意。你可以使用Configuration中的toString檢視各個xml檔案的載入順序,使用dumpConfiguration列印每個屬性的來源及isFinal屬性值