Hadoop 配置文件的格式
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>io.sort.factor</name>
<value>10</value>
<description>The number of streams to merge at once while sorting files. This determines the number of open file handles.</description>
</property>
<property>
<name>dfs.name.dir</name>
<value>${hadoop.tmp.dir}/dfs/name</value>
<description>Determines where on the local filesystem the DFS name nodeshould store the name table(fsimage). ……</description>
</property>
<property>
<name>dfs.web.ugi</name>
<value>webuser,webgroup</value>
<final>true</final>
<description>The user account used by the web interface.Syntax: USERNAME,GROUP1,GROUP2, ……</description>
</property>
</configuration>
Hadoop 配置文件的根元素是 configuration,一般只包含子元素 property。每一个property 元素就是一个配置项,配置文件不支持分层或分级。每个配置项一般包括配置属性的名称 name、值 value 和一个关于配置项的描述 description ;元素 final 和 Java 中的关键字
final 类似,意味着这个配置项是“固定不变的”。final 一般不出现,但在合并资源的时候,可以防止配置项的值被覆盖。
合并资源指将多个配置文件合并,产生一个配置。如果有两个配置文件,也就是两个资源,如 core-default.xml 和 core-site.xml,通过 Configuration 类的 loadResources() 方法,把它们合并成一个配置。代码如下:
Configurationconf = new Configuration();
conf.addResource(“core-default.xml”);
conf.addResource(“core-site.xml”);
如果这两个配置资源都包含了相同的配置项,而且前一个资源的配置项没有标记为final,那么,后面的配置将覆盖前面的配置。上面的例子中,core-site.xml 中的配置将覆盖core-default.xml 中的同名配置。如果在第一个资源(core-default.xml)中某配置项被标记为final,那么,在加载第二个资源的时候,会有警告提示。
Hadoop 配置系统还有一个很重要的功能,就是属性扩展。如配置项 dfs.name.dir 的值是${hadoop.tmp.dir}/dfs/name,其中,${hadoop.tmp.dir} 会使用 Configuration 中的相应属性值进行扩展。如果 hadoop.tmp.dir 的值是“/data”,那么扩展后的 dfs.name.dir 的值就是“/data/dfs/name”。
使 用 Configuration 类 的 一 般 过 程 是 : 构 造 Configuration 对 象, 并 通 过 类 的addResource() 方法添加需要加载的资源 ;然后就可以使用 get 方法和 set 方法访问 / 设置配置项,资源会在第一次使用的时候自动加载到对象中。
Configuration 的成员变量
布尔变量quietmode,用来设置加载配置的模式。如果quietmode为true (默认值),则在加载解析配置文件的过程中,不输出日志信息。quietmode只是一个方便开发人员调试的变量。
数组resources保存了所有通过addResource( ) 方法添加Congiguation对象的资源。
布尔变量 loadDefaults 用于确定是否加载默认资源,这些默认资源保存在 defaultResources中。注意,defaultResources 是个静态成员变量,通过方法 addDefaultResource() 可以添加系统的默认资源。在 HDFS 中,会把 hdfs-default.xml 和 hdfs-site.xml 作为默认资源,并通过addDefaultResource() 保存在成员变量defaultResources 中 ;在 MapReduce 中,默认资源是mapred-default.xml 和 mapred-site.xml。如 HDFS 的 DataNode 中,就有下面的代码,加载上述两个默认资源:
static{
Configuration.addDefaultResource("hdfs-default.xml");
Configuration.addDefaultResource("hdfs-site.xml");
}
properties、overlay 和 finalParameters 都是和配置项相关的成员变量。其中,properties和 overlay 的类型都是前面介绍过的 java.util.Properties。Hadoop 配置文件解析后的键 – 值对,都存放在 properties 中。变量 finalParameters 的类型是 Set,用来保存所有在配置文件中已经被声明为 final 的键 – 值对的键,如前面配置文件例子中的键“dfs.web.ugi”。变量overlay 用于记录通过 set() 方式改变的配置项。也就是说,出现在 overlay 中的键 – 值对是应用设置的,而不是通过对配置资源解析得到的。
Configuration 中最后一个重要的成员变量是 classLoader,这是一个类加载器变量,可以通过它来加载指定类,也可以通过它加载相关的资源。上面提到 addResource() 可以通过字符串方式加载 CLASSPATH 资源,它其实通过 Configuration 中的 getResource() 将字符串转换成 URL 资源,相关代码如下:
public URL getResource(String name) {
return classLoader.getResource(name);
}
其中,getResource() 用于根据资源的名称查找相应的资源,并返回读取资源的 URL 对象。
资源加载
资源通过对象的 addResource() 方法或类的静态 addDefaultResource() 方法(设置了loadDefaults 标志)添加到 Configuration 对象中,添加的资源并不会立即被加载,只是通过reloadConfiguration() 方法清空 properties 和 finalParameters。
Configurable 接口
从字面理解,Configurable 的含义是可配置的,如果一个类实现了 Configurable 接口,意味着这个类是可配置的。也就是说,可以通过为这个类的对象传入一个 Configuration 实例,提供对象工作需要的一些配置信息。Hadoop 的代码中有大量的类实现了 Configurable 接口,如
org.apache.hadoop.mapred.SequenceFileInputFilter.RegexFilter。
RegexFilter 对象工作时,需要提供一个正则表达式,用于过滤读取的记录。由于 RegexFilter的父类 Filter 中实现的 Configurable 接口,RegexFilter 可以在它的 setConf() 方法中,使用Configuration.get() 方法获取以字符串传入的正则表达式,并初始化成员变量 p。相关代码如下:
public void setConf(Configuration conf) {
String regex = conf.get(FILTER_REGEX);
if (regex==null)
throw new RuntimeException(FILTER_REGEX + "not set");
this.p = Pattern.compile(regex);
this.conf = conf;
}
Configurable.setConf() 方法何时被调用呢?一般来说,对象创建以后,就应该使用setConf() 方法,为对象提供进一步的初始化工作。