国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

hadoop中Configuration類剖析

2019-11-14 22:11:47
字體:
供稿:網(wǎng)友
hadoop中Configuration類剖析Configuration是hadoop中五大組件的公用類,所以放在了core下,org.apache.hadoop.conf.Configruration。這個類是作業(yè)的配置信息類,任何作用的配置信息必須通過Configuration傳遞,因為通過Configuration可以實現(xiàn)在多個mapper和多個reducer任務(wù)之間共享信息。

類圖

說明:Configuration實現(xiàn)了Iterable和Writable兩個接口,其中實現(xiàn)Iterable是為了迭代,迭代出Configuration對象加載到內(nèi)存中的所有name-value鍵值對。實現(xiàn)Writable是為了實現(xiàn)hadoop框架要求的序列化,可以將內(nèi)存中的name-value序列化到硬盤,關(guān)于這兩個接口的具體實現(xiàn)的話,我想不用再多說了,應(yīng)該想的明白。下面來詳細(xì)的分析下Configuration的工作原理,包含配置文件的加載,獲取配置信息和加載配置信息的原理,以及在使用過程中應(yīng)該注意的事項。研究任何一個類首先從構(gòu)造函數(shù)開始,就算是使用的單例,靜態(tài)工廠得到對象也同樣離不開Constructor。Configuration有三個構(gòu)造函數(shù)
public Configuration() {    this(true);  }/** A new configuration where the behavior of reading from the default    * resources can be turned off.   *    * If the parameter {@code loadDefaults} is false, the new instance   * will not load resources from the default files.    * @param loadDefaults specifies whether to load from the default files   */  public Configuration(boolean loadDefaults) {    this.loadDefaults = loadDefaults;    updatingResource = new HashMap<String, String>();    synchronized(Configuration.class) {      REGISTRY.put(this, null);    }  }/**    * A new configuration with the same settings cloned from another.   *    * @param other the configuration from which to clone settings.   */  @Sup1,Configuration()2,Configuration(boolean loadDefaults)3, Configuration(Configuraiont other) 前兩個Constructor使用的是典型的重疊構(gòu)造器模式,也就是默認(rèn)的無參Constructor會生成一個加載了默認(rèn)配置文件得Configuration對象,其中Configuration(boolean loadDefaults)中的參數(shù)就是為了控制構(gòu)造出來的對象是加載了默認(rèn)配置文件還是沒有的標(biāo)識。但是如果要我來設(shè)計我不會搞得這么麻煩,直接使用兩個靜態(tài)工廠方法來標(biāo)識不同性質(zhì)的對象——getConfigruationWithDefault()和getConfiguration,這樣的話開發(fā)人員在使用是就可以望文生義,不是很好的方式么?不扯這個了。當(dāng)loadDefaults為false時,Configuration對象就不會將通過addDefaultResource(String resource)加載的配置文件載入內(nèi)存。但是會將通過addResource(...)加載的配置文件載入內(nèi)存。具體是怎么實現(xiàn)的呢?  在Configuration這個Constructor中的this.loadDefaults = loadDefaults就是設(shè)置是否加載默認(rèn)配置文件的flag,我們順蔓摸瓜,構(gòu)造了Configuration對象后,接下來會調(diào)用getType(String name,Type default)方法得到某個name對應(yīng)的value值。以getInt為例,看看getInt()的代碼getInt(String name,int defalutVale)
public int getInt(String name, int defaultValue) {    String valueString = get(name);    if (valueString == null)      return defaultValue;    try {      String hexString = getHexDigits(valueString);      if (hexString != null) {        return Integer.parseInt(hexString, 16);      }      return Integer.parseInt(valueString);    } catch (NumberFormatException e) {      return defaultValue;    }  }
方法的第一行代碼String valueString = get(name);是關(guān)鍵,所以再來看看get(String name)這個方法get(String name)
private synchronized Properties getProps() {    if (properties == null) {      properties = new Properties();      loadResources(properties, resources, quietmode);      if (overlay!= null) {        properties.putAll(overlay);        for (Map.Entry<Object,Object> item: overlay.entrySet()) {          updatingResource.put((String) item.getKey(), UNKNOWN_RESOURCE);        }      }    }    return properties;  }
這里就有話可講了,由getInt --> get --> getProps的路徑是任何一次getType方法調(diào)用要走的路徑,但是在getProps()這個地方就要分道揚(yáng)鑣了,第一次用getType方法在判斷了properties == null后會執(zhí)行l(wèi)oadResources(properties,resources,quietmode)方法。但是在properties不為null的情況下就不會執(zhí)行后續(xù)代碼。下面走進(jìn)loadResources(properties,resources,quietmode)方法一探究竟loadResources(properties,resources,quietmode)
private void loadResources(Properties properties,                             ArrayList resources,                             boolean quiet) {    if(loadDefaults) {      for (String resource : defaultResources) {        loadResource(properties, resource, quiet);      }          //support the hadoop-site.xml as a deprecated case      if(getResource("hadoop-site.xml")!=null) {        loadResource(properties, "hadoop-site.xml", quiet);      }    }        for (Object resource : resources) {      loadResource(properties, resource, quiet);    }  }

看到了loadDefaults了沒有?是不是很開心,在Constructor涉及到的控制默認(rèn)配置文件加載的loadDefaults終于現(xiàn)身了。defaultResource在loadDefaults為true是才會加載。但是resources中存放的配置文件無論怎么樣都會被加載,這里出現(xiàn)了兩個存放配置文件的容器defaultResources和resource

/**   * List of configuration resources.   */  private ArrayList<Object> resources = new ArrayList<Object>();/**   * List of default Resources. Resources are loaded in the order of the list    * entries   */  private static final CopyOnWriteArrayList<String> defaultResources =    new CopyOnWriteArrayList<String>();
一個是cofiguration resources的list,一個default Resources的list,那么如何區(qū)分是否是default resources呢?別著急,看下面的分析。在Configuration類中有多個加載配置文件的方法,addDefaultResource(String name),addResource(String resoruce)及重載方法,addResourceObject(Object resource)。由于addResource(...)系類的方法最終是通過調(diào)用addResourceObject來實現(xiàn)的,所以這個就要看addDefaultResource(String name)和addResourceObject(Object resource)的區(qū)別了addDefaultResource(String resource)
public static synchronized void addDefaultResource(String name) {    if(!defaultResources.contains(name)) {      defaultResources.add(name);      for(Configuration conf : REGISTRY.keySet()) {        if(conf.loadDefaults) {          conf.reloadConfiguration();        }      }    }  }

addResourceObject(Object object)

private synchronized void addResourceObject(Object resource) {    resources.add(resource);                      // add to resources    reloadConfiguration();  }
看清楚沒有?沒看清楚多看一下。addDefaultResource(String name)內(nèi)部通過defaultResources.add(name)將配置文件的name加入了容器defaultResources容器中,addResourceObject(Object resource)通過resources.add(resource)將配置文件加入了resources容器中。所以這就說明了,所以的默認(rèn)配置文件是通過addDefaultResource(String name)加載的,也就存放在defaultResources這個容器中的,存放在resources中的配置文件就不能當(dāng)做是默認(rèn)的配置文件了。 仔細(xì)觀察這兩個方法的實現(xiàn),發(fā)現(xiàn)reloadConfiguration(),這里面有文章可以做,還是看源碼說話吧reloadConfiguration()
/**   * Reload configuration from previously added resources.   *   * This method will clear all the configuration read from the added    * resources, and final parameters. This will make the resources to    * be read again before accessing the values. Values that are added   * via set methods will overlay values read from the resources.   */  public synchronized void reloadConfiguration() {    properties = null;                            // trigger reload    finalParameters.clear();                      // clear site-limits  }
恩,properties=null,fianlParmeters.clear(),這就將內(nèi)存中存在的name-value都清空了。所以在使用getType方法后又得重新將配置文件載入內(nèi)存,所以建議在作業(yè)運行的過程中不要使用addDefaultResource(String resource)和addResourceObject(Object object),因為這會導(dǎo)致重新加載配置文件到內(nèi)存。有必要解釋下finalParameters這個filed,該feilds也是一個Set容器,主要是用來存儲被final修飾的name-value,被fianl修飾后的name-value無法被后續(xù)的配置文件覆蓋,但是在程序中可以通過set(String name,String value),這里讓人不明白,不允許管理員通過配置文件修改的name-value但是可以被用戶修改,實則是很奇怪。關(guān)于第三個構(gòu)造函數(shù),根據(jù)參數(shù)和具體實現(xiàn)很容易知道是生成一個和傳入的configuration對象一樣的configuration對象,不說了這里。 現(xiàn)在關(guān)于構(gòu)造Configuration對象時如何控制是否加載的配置文件原理已經(jīng)清楚了,同時也弄清楚了getType的原理。下面是調(diào)用getType方法的時序圖   構(gòu)造器,getType原理應(yīng)該已經(jīng)清楚了,現(xiàn)在來看下setType方法,setType(String name ,Type value)方法內(nèi)部都調(diào)用了set(String name,String value)方法,這一點和getType(String name,Type defaultValue)與get(String)的關(guān)系是相同的。那么現(xiàn)在來思考一個問題:上面說了,在使用addDefaultResources(...)和addResourceObject(...)方法都會清空內(nèi)存中的name-value鍵值對,放在配置文件中的name-value可以重新加載到內(nèi)存中,也就說這些name-value鍵值對并不會丟失。但是通過setType()設(shè)置的值別沒有寫到配置文件中,他們是存在內(nèi)存當(dāng)中。
public void set(String name, String value) {    getOverlay().setProperty(name, value);    getProps().setProperty(name, value);    this.updatingResource.put(name, UNKNOWN_RESOURCE);  }
getProps返回的是存放有所有的name-value鍵值對的Properties對象,使用set(String name,String value)方法設(shè)置的name-value僅僅是放在了properties對象的內(nèi)存空間總并沒有寫入到文件,這樣addDefaultResources(...)和addResourceObject(...)時properties被設(shè)置為null后,好不容易通過set(String name,String value)加載進(jìn)來的name-value豈不是丟棄了? 注意在set(String name,String value)中還有一個地方是關(guān)鍵getOverlay().setProperty(name, value),其中g(shù)etOverlay()方法返回的overlay,該對象的引用類型是Properties。矛盾來了,set(String name,String value)方法將name-value加到了兩個Properties對象中,這又是干什么?呀,現(xiàn)在可以肯定的是通過set(String name,String value)方法設(shè)置的name-value鍵值對在字段overlay對象和字段properties都有,在回頭來看看getProps()方法
private synchronized Properties getProps() {    if (properties == null) {      properties = new Properties();      loadResources(properties, resources, quietmode);      if (overlay!= null) {        properties.putAll(overlay);        for (Map.Entry<Object,Object> item: overlay.entrySet()) {          updatingResource.put((String) item.getKey(), UNKNOWN_RESOURCE);        }      }    }    return properties;  }
在properties為null的條件下,除了會去加載配置文件中value-name,還會探測一下overlay對象是不是為空,不為空就將overlay對象中的name-value加載到properties中,恩,這一點和reloadConfiguration()不矛盾,因為reloadConfiguration()是將properties對象置為 null,并沒有將overlay置為空??梢赃@樣說overlay的作用是將用戶設(shè)置的name-value保存起來作為properties在內(nèi)存部分的備份,這樣properties中由系統(tǒng)和管理員配置的name-value由配置文件備份,而后期用戶載入的name-value則有overlay備份到內(nèi)存中,properties在configuration對象存活期間不會有信息丟失。setType和getType方法都可以觸發(fā)loadResources()方法將name-value加入到properties對象的內(nèi)存中,但是一旦properties已經(jīng)存放了配置文件中的name-value鍵值對,再次調(diào)用setType或者是getType方法就不會觸發(fā)loadResources()的加載動作,除非調(diào)用了addDefaultResources(...)和addResourceObject(...)。Summarize:1 在作業(yè)運行過程中不要使用addDefaultResources(...)和addResourceObject(...)加載資源,因為這會導(dǎo)致properties對象重構(gòu)一遍,建議此時使用setType(...)2 Configuration在整個MapReduce中使用得很頻繁,JobTraker,TaskTraker進(jìn)程在啟動的時候都會使用到Configuration對象,HDFS中同樣也會使用Configuration對象,所以我認(rèn)為理解Configuration的基本工作原理很重要。3 Configuration可以用來在MapReduce任務(wù)之間共享信息,當(dāng)然這樣共享的信息是在作業(yè)中配置,一旦作業(yè)中的map或者reduce任務(wù)啟動了,configuration對象就完全獨立。所以共享信息是在作業(yè)中設(shè)置的。?


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 白山市| 那曲县| 和林格尔县| 巧家县| 盐山县| 河曲县| 措美县| 鹤峰县| 灵丘县| 涞源县| 新建县| 安康市| 大方县| 灌阳县| 涪陵区| 镇康县| 浦江县| 唐河县| 新巴尔虎左旗| 台中县| 威宁| 谷城县| 沈阳市| 乐平市| 于都县| 岳池县| 石家庄市| 贡觉县| 泰宁县| 彝良县| 龙陵县| 襄樊市| 朝阳区| 成武县| 布尔津县| 榆林市| 新巴尔虎左旗| 桃园市| 左贡县| 桃园市| 平塘县|