Hadoop中的组件是通过Hadoop自己的配置API来配置的。一个Configuration类的实例(可以在org.apache.hadoop.conf包中找到)代表配置属性及其取值的一个集合。每个属性由一个String来命名,而值的类型可以是多种类型之一,包括Java基本类型(如boolean、int、long和float)、其他有用的类型(如String、Class和java.io.File)及String集合。
Configuration从资源(即使用简单结构定义名值对的XML文件)中读取其属性值。参见下面范例。
color
yellow
Color
size
10
Size
weight
heavy
true
Weight
size-weight
${size},${weight}
Size and weight
假定一个Configuration位于上面的文件中,我们可以通过如下代码访问其属性:
Configuration conf = new Configuration();
conf.addResource("configuratoin-1.xml");
assertThat(conf.get("color"), is("yellow"));
assertThat(conf.getInt("size", 0), is(10));
assertThat(conf.get("breadth", "wide"), is("wide"));
有这样几点需要注意:XML文件中不保存类型信息;取而代之的是属性在被读取的时候,可以被解释为指定的类型;此外,get()方法允许为XML文件中没有定义的属性指定默认值,正如这一代码中最后一行的breadth属性一样。
使用多个资源文件来定义一个Configuration时,事情变得有趣了。在Hadoop中,这用于分离(core-default.xml文件内部定义的)系统默认属性与(core-site.xml文件中定义的)位置相关(site-specific)的覆盖属性。下面范例中的文件定义了size属性和weight属性。
size
12
weight
light
资源文件按顺序把上面两个配置文件信息添加到Configuration:
Configuration conf = new Configuration();
conf.addResource("configuration-1.xml");
conf.addResource("configuration-2.xml");
后来添加到资源的属性会覆盖(override)之前定义的属性。所以,size属性的取值来自于第二个配置文件configuration-2.xml:
assertThat(conf.getInt("size", 0), is(12));
不过,被标记为final的属性不能被后面的定义被覆盖。在第一个配置文件中,weight属性的final状态是true,因此,第二个配置文件中的覆盖设置失败,weight取值仍然是第一个配置文件中的heavy:
assertThat(conf.get("weight"), is("heavy"));
试图覆盖final属性通常意味着配置错误,所以最后会弹出警告消息来帮助进行故障诊断。一般来说,管理员将守护进程站点中的属性标记为final,表明他们不希望用户在客户端的配置文件或作业提交参数(job submission parameter)中有任何改动。
配置属性可以用其他属性或系统属性进行定义。例如,在第一个配置文件中的size-weight属性可以定义为${size}和${weight},而且这些属性是用配置文件中的值来扩展的:
assertThat(conf.get("size-weight"), is("12,heavy"));
系统属性的优先级高于资源文件中定义的属性:
System.setProperty("size", "14");
assertThat(conf.get("size-weight"), is("14 , heavy"));
该特性特别适用于在命令行方式下用JVM参数-Dproperty=value来覆盖属性。
注意,虽然配置属性可以通过系统属性来定义,但除非系统属性使用配置属性重新定义,否则,他们是无法通过配置API进行访问的。因此:
System.setProperty("size", "2");
assertThat(conf.get("length"), is((String) null));