1. 程式人生 > >Hadoop 配置API

Hadoop 配置API

Hadoop配置

本文章在其他文章基礎上參考編輯

Hadoop配置API

hadoop中的元件都是通過Hadoop自己的配置API配置的,一個Configuration類的例項代表了Hadoop叢集的配置。配置類似於Map,由屬性及值組成。屬性為String型別,值則可以為java基本型別、其他有用型別(例如String、Class、java.io.File)及String集合。

API重要屬性

  • quitemode:boolean型別,配置資訊載入過程中,是否處於安靜模式,即有一些資訊不會被記錄,預設是true;
  • resources:ArrayList型別,Resource是Configuration的內部類,有兩個屬性Object resource和String name;resources是一個物件陣列,用於儲存有關包含配置資訊的物件;
  • finalParameters:Set型別,所有被宣告為final的變數集合,宣告為final就表示不能被後續覆蓋;
  • loadDefaults:boolean型別,是否載入預設配置;
  • REGISTRY:WeakHashMap<Configuration,Object>型別,用於多個物件的相關配置的註冊及對它們進行管理,記錄了所有的Configuration;
  • defaultResources:CopyOnWriteArrayList型別,用於儲存預設的配置資源名或路徑;
  • properties:java內建的Properties型別,儲存所有配置資訊,KV值;
  • overlay:Properties型別,是使用者設定的而不是通過對資源解析得到的;
  • classloader:ClassLoader型別,主要用於載入指定的類或者載入相關資源;
  • updatingResource:HashMap<String, String[]>型別,儲存最近載入或修改的屬性
  • VAR_PATTERN:靜態Pattern型別,用於正則匹配,Pattern.compile("\$\{[\}\$\u0020]+\}"),正則表示式中$、{、}都是保留字,所以需要用"“進行轉義,“\$\{”用於匹配${key}中的key前面的”${";最後的"\}“用於匹配key後的”}";中間部分"[
    \}\KaTeX parse error: Can't use function '\u' in math mode at position 1: \̲u̲0020]+"用於匹配屬性擴充套件…"、"}“和空格(\u0020指的是空格)以外的所有字元,還有”+"出現至少1次。
  • MAX_SUBST:靜態int型別,預設值是20,MAX_SUBST是設定對帶有環境變數的值所能夠深入解析的層次數,超出這個最大的層數的值將不能夠解析。

API初始化

  1. 靜態程式碼塊: 呼叫構造方法之前執行,會載入core-default.xml和core-site.xml兩個檔案,Configuration的子類也會同樣載入這兩個檔案。
static {
        deprecationContext = new AtomicReference(new Configuration.DeprecationContext((Configuration.DeprecationContext)null, defaultDeprecations));
        ClassLoader cL = Thread.currentThread().getContextClassLoader();
        if (cL == null) {
            cL = Configuration.class.getClassLoader();
        }

        if (cL.getResource("hadoop-site.xml") != null) {
            LOG.warn("DEPRECATED: hadoop-site.xml found in the classpath. Usage of hadoop-site.xml is deprecated. Instead use core-site.xml, mapred-site.xml and hdfs-site.xml to override properties of core-default.xml, mapred-default.xml and hdfs-default.xml respectively");
        }

        addDefaultResource("core-default.xml");
        addDefaultResource("core-site.xml");
        VAR_PATTERN = Pattern.compile("\\$\\{[^\\}\\$ ]+\\}");
    }
  1. 構造方法:
  • Configuration():呼叫引數為true的構造方法。
  • Configuration(boolean loadDefaults):確認是否載入預設配置。
  • Configuration(Configuration other):第三個就是將指定的Configuration物件重新複製一份。
  1. 載入資源
    可以通過Configuration的addResource()方法或者靜態方法addDefaultResource()(設定了loadDefaults標誌)來新增資源到Configuration中。但是add之後資源並不會立即被載入,hadoop的Configuration被設計成了“懶載入”,即在需要時才會被載入。在add之後會呼叫reloadConfiguration()方法清空properties和finalParameters。
    • addDefaultResource()方法,這是一個靜態方法。通過這個方法可以新增系統的預設資源。在HDFS中會被用來載入hdfs-default.xml和hdfs-site.xml;在MapReduce中會被用來載入mapred-default.cml和mapred-site.xml,可以在相關的Configuration子類中找到相應地靜態程式碼塊。
    • addResource方法,該方法有6種形式,也就是可以add的形式:可以是一個輸入流、HDFS檔案路徑、WEB,URL、CLASSPATH資源、以及Configuration物件。這些方法都會將引數封裝成Resource物件後,傳遞給addResourceObject方法並呼叫該方法。在addResourceObject方法中會將Resource物件加入resources中並呼叫reloadConfiguration方法
  2. 屬性獲取
    見:https://www.cnblogs.com/lxf20061900/p/4189727.html

配置屬性特性

  • 配置可以被覆蓋,也可以被系統屬性或其他屬性重新定義。一般優先順序為:系統定義(例如命令列模式下用JVM引數-Dproperty=value覆蓋資原始檔中的該屬性定義) > 資原始檔定義
  • 資原始檔中被標記為final的屬性無法被覆蓋
  • 系統屬性可以覆蓋配置屬性,但是如果定義了系統屬性,但沒有定義同名的配置屬性,則無法通過該API訪問。

配置管理

管理配置的目的

開發Hadoop應用時,經常需要在本地執行和叢集執行之間切換,因此通過不同Hadoop配置檔案包含各個叢集配置,在執行時指定連線。

基於環境變數

通過配置HADOOP_CONF_DIR。當使用Configuration conf = new Configuration()時Hadoop會自動載入該變數指向的目錄下的資原始檔。

通過Hadoop自帶工具的-conf引數配置

使用方法:hadoop fs -conf [config local path] [cmd]
使用例子:hadoop fs -conf conf/hadoop-local.xml -ls /

通過使用Tool介面實現

GenericOptionParser

該類的主要作用是通過解析常用的Hadoop命令列選項,併為Configuration物件是指相應的取值。不過通常情況下不使用該類,而是實現Tool介面,通過ToolRunner類執行。後者內部呼叫該類。

Tool和ToolRunner

在下面的例項中,ConfigurationPrinter作為Configured的一個子類,ConfiguredConfigurable介面的一個實現
資原始檔:
example/resource_1.xml

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <property>
        <name>sizes</name>
        <value>10</value>
    </property>
    <property>
        <name>weight</name>
        <value>50</value>
        <final>true</final>
    </property>
    <property>
        <name>size-weigh</name>
        <value>${sizes},${weight},${test}</value>
    </property>
</configuration>

example-resource_2.xml

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <property>
        <name>sizes</name>
        <value>1</value>
    </property>
    <property>
        <name>weight</name>
        <value>20</value>
        <final>true</final>
    </property>
</configuration>

使用示例:

package chapter6;
/*
 * @author 趙鵬越
 * @date 2018/11/2
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.util.Map;

/**
 * 用於解析命令列引數
 * hadoop chapter6.ConfigurationPrinter -D color=value |egrep 'color|weight|sizes|size-weigh|test'
 * 注:
 * -D 設定一個屬性鍵值對
 * out:
 * color=value
 */
public class ConfigurationPrinter extends Configured implements Tool {

    static {
        // 載入配置檔案
        Configuration.addDefaultResource("hadoop/core-site.xml");
        Configuration.addDefaultResource("hadoop/hdfs-site.xml");
        Configuration.addDefaultResource("hadoop/mapred-site.xml");
        Configuration.addDefaultResource("hadoop/yarn-site.xml");
    }

    public int run(String[] strings) throws Exception {
        // 所有命令列引數都會載入到下面的Configuration物件中
        Configuration conf = getConf();
        for (Map.Entry<String, String> entry: conf) {
            System.out.printf("%s=%s\n", entry.getKey(), entry.getValue());
        }
        // 系統變數配置sizes,優先順序最高
        System.setProperty("sizes", "12");
        conf.addResource("example/resource_1.xml");
        conf.addResource("example/resource_2.xml");
        // 系統變數test在資源未見中未定義,可引用,但是無法獲取
        System.setProperty("test", "12");
        // 系統變數優先順序較高,輸出12
        System.out.println("sizes: " + conf.get("sizes"));
        // resource_1檔案中標記為final屬性,故輸出50
        System.out.println("weight: " + conf.get("weight"));
        // 引用相關變數,故輸出12,50,12
        System.out.println("size-weigh: " + conf.get("size-weigh"));
        // 系統變數test在資源未見中未定義,可引用,但是無法獲取,輸出null
        System.out.println("test: " + conf.get("test"));
        return 0;
    }

    public static void main(String[] args) throws Exception {
        int exitCode = ToolRunner.run(new ConfigurationPrinter(), args);
        System.exit(exitCode);
    }
}
// STDOUT
sizes: 1
weight: 50
size-weigh: 12,50,12
test: null