《Hadoop权威指南》ch6 MapReduce配置

Hadoop Configuration API

Hadoop中的组件Components是通过Hadoop自带的API进行配置的。一个Configuration类(org.apache.hadoop.conf)的实例代表配置属性及其取值的一个集合。每个属性有一个String进行命名并作为一个key,而值的类型包括Java的基本类型如(boolean、int、long、float等)。Configuration实例可以从XML文件中读取属性值。

XML配置文件的创建及使用

  • 一个简单的配置文件configuration-1.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="UTF-8"?>

    <configuration>
    <property>
    <name>color</name>
    <value>yellow</value>
    </property>
    <property>
    <name>size</name>
    <value>10</value>
    </property>
    <property>
    <name>weight</name>
    <value>heavy</value>
    <final>true</final>
    </property>
    <property>
    <name>size-weight</name>
    <value>${size},${weight}</value>
    </property>
    </configuration>

配置文件需要放置在MapReduce项目的src目录下。
xml 配置文件路径
实例化Configuration,并使用get()方法获取指定属性的值。另外,get()方法允许为XML文件中没有定义的属性指定默认值。

  • Java代码如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import org.apache.hadoop.conf.*;

    public class TestConfiguration {

    public static void main(String[] args) throws Exception{
    Configuration conf = new Configuration();
    conf.addResource("configuration-1.xml");

    System.out.println(conf.get("color")); // 输出为“yello”
    System.out.println(conf.getInt("size", 0)); // 输出为10
    System.out.println(conf.get("breadth", "wide")); //输出为“wide”
    }
    }

资源合并(Combining Resource)

Configuration类是添加多个配置文件的,后来添加到资源文件的属性会覆盖之前的定义属性。但若属性的final值为true的话,意味该属性值不能被后面的定义所覆盖。若尝试着覆盖,将会弹出警告消息帮助进行故障诊断。

  • 第二个配置文件configuration-2.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8"?>

    <configuration>
    <property>
    <name>size</name>
    <value>12</value>
    </property>
    <property>
    <name>weight</name>
    <value>light</value>
    </property>
    </configuration>
    • Java代码如下
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      import org.apache.hadoop.conf.*;

      public class TestConfiguration {

      public static void main(String[] args) throws Exception{
      Configuration conf = new Configuration();
      conf.addResource("configuration-1.xml");
      conf.addResource("configuration-2.xml");

      System.out.println(conf.getInt("size", 0)); // 输出为12,size属性值被第二个配置文件覆盖
      System.out.println(conf.get("weight")); // 输出为"light",weight属性的final值为true,无法被覆盖输出不变
      }
      }

因尝试着override weight属性值,报以下警告
override warn

变量扩展(Variable Expansion)

配置文件可以定义配置属性,如第一个配置文件中,size-weight订了${size}和${weight}。
此外,在程序中可以另外定义系统属性,系统属性的优先级高于资源文件中定义的配置属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.apache.hadoop.conf.*;

public class TestConfiguration {

public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
conf.addResource("configuration-1.xml");
conf.addResource("configuration-2.xml");

System.setProperty("size", "14"); // 配置属性可以用系统属性进行定义
System.setProperty("weight", "super heavy");
System.out.println("系统属性size为 " + System.getProperty("size")); // 输出为14
System.out.println("系统属性weight为 " + System.getProperty("weight")); // 输出为super heavy
System.out.println("配置属性size为 " + conf.get("size")); // 输出值仍为12
System.out.println("配置属性weight为 " + conf.get("weight")); // 输出值仍为light

}

}

辅助类GenericOptionsParser, Tool和ToolRunner

Hadoop提供了辅助类,GenericOptionsParser:用来解释常用的Hadoop命令选项,但是一般更常用的方式:实现Tool接口,通过ToolsRunner来运行程序,ToolRunner内部调用GenericOptionsParser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package configuration;
import java.util.Map.Entry;

import org.apache.hadoop.conf.*;
import org.apache.hadoop.util.*;

public class ConfigurationPrinter extends Configured implements Tool {
// 将配置文件添加进资源,若配置无需修改(即src文件夹无配置文件),则无需执行
// static {
// Configuration.addDefaultResource("hdfs-default.xml");
// Configuration.addDefaultResource("hdfs-site.xml");
// Configuration.addDefaultResource("mapred-default.xml");
// Configuration.addDefaultResource("mapred-site.xml");
// }

@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
for (Entry<String, String> entry : conf) {
System.out.printf("%s=%s\n", entry.getKey(), entry.getValue());
}
return 0;
}

public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(new ConfigurationPrinter(), args);
System.exit(exitCode);
}
}

ConfigurationPrinter的main()没有直接调用自身的run(),而是调用了ToolRunner的静态run()方法,该方法在调用自身的run()之前,为Tool建立一个Configuration对象。

Have a nice day!