Hadoop Common 之Configuration类小解
1.Configuration主要配置来源
方式一: conf.set(键,值)
方式二:conf.addResource(字符串或者PATH路径) //加载用户自定义配置文件
方式三:conf.addDefaultResource(字符串或者PATH路径) //添加用户默认配置文件
方式四:setSocketAddr添加配置项----此处不多说
2.Configuration类定义
public class Configuration implements Iterable<Map.Entry<String,String>>,
Writable {
由于数据的计算处理需要分布式处理,所以要保证计算的每台节点上都要应用这样的配置,因此需要实现序列化接口Writable
,而Iterable<Map.Entry<String,String>>则是为了提供给外部访问。
3.Configuration的配置主要属性
1) resources: 类型:ArrayList指的是用户配置配置目录中通过Resource添加的配置文件
2)defaultResources:ArrayList,与resources类似,只不过是加载默认配置的,这些配置包括Common模块或者其他模块中自引用的core-default.xml与core-site.xml,hdfs-default.xml等,还包括用户通过addDefaultResource指定的配置文件,或者用户在资源目录中拷贝或者添加的与core-default.xml与core-site.xml,hdfs-default.xml同名配置文件中的配置,甚至还包括log4j.properties
3) finalParameters: 类型是Set,主要存储的是用户自定义配置(addResource,addDefaultResource等方式)中使用true的配置项,表示该配置项是不可以被在此修改的(conf.set模式可以修改,排除在外)
先看看被修饰为final的配置有哪些:
Set<String> finalParameters = fs.getConf().getFinalParameters();
for (String finalParameter : finalParameters) {
System.out.println(finalParameter);
}
输出结果:
mapreduce.job.end-notification.max.retry.interval
mapreduce.job.end-notification.max.attempts
现在以mapreduce.job.end-notification.max.retry.interval
为例:原本其值是5000
现在添加1.xml文件作为用户自定义配置:
1.xml文件内容
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>mapreduce.job.end-notification.max.retry.interval</name>
<value>7000</value>
</property>
</configuration>
输出:
System.out.println(fs.getConf().get("mapreduce.job.end-notification.max.retry.interval"));
结果还是:5000 //即没有被修改—也就意味着这项是没有被修改的
现在再1.xml配置文件中添加如下配置:
<property>
<name>dfs.replication</name>
<value>4</value>
<final>true</final>
</property>
然后输出:
System.out.println(fs.getConf().get(“dfs.replication”)); // 4
我现在添加配置文件2.xml:
?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
<final>true</final>
</property>
</configuration>
因此程序中就有了:
conf.addResource("1.xml");
conf.addResource("2.xml");
在此输出:
System.out.println(fs.getConf().get(“dfs.replication”)); // 4
发现没有被修改,副本数还是4,这就是final标签的作用,不过这个配置可以通过conf.set()来修改
4)properties:类型为Properties,主要用来配置文件中的解析的键值对存储到properties中
eg: hadoop-hdfs模块中默认配置文件hdfs-site.xml副本数设置的一段配置
<property>
<name>dfs.replication</name>
<value>3</value>
<description>Default block replication.
The actual number of replications can be specified when the file is created.
The default is used if replication is not specified in create time.
</description>
</property>
打印输出这段结果:
System.out.println(fs.getConf().get(“dfs.replication”)); // 3
现在添加1.xml文件作为用户自定义配置:
1.xml文件内容
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>mapreduce.job.end-notification.max.retry.interval</name>
<value>7000</value>
</property>
<property>
<name>dfs.replication</name>
<value>4</value>
</property>
</configuration>
程序中添加自定义配置文件
conf.addResource("1.xml");
打印输出结果:
System.out.println(fs.getConf().get(“dfs.replication”)); // 2
很明显配置生效了。
5)overload:Properties类型,存储的是通过conf.set()方法设置的配置
eg:
conf.set("fs.defaultFS","hdfs://mkmg/");
输出结果:
System.out.println(fs.getConf().get(“fs.defaultFS”)); // hdfs://mkmg/
4.配置文件的加载
配置文件通过Configuration类的对象实例的addResource或者Configuration类的静态addDefaultResource方法,添加到Configuration对象中的resource中,但是并不会立即被加载—而是会调用reloadConfiguration方法清空properties或者finalParameters。
1)用户自定义配置文件(非默认配置文件)的加载
/**
* Add a configuration resource.
*
* The properties of this resource will override properties of previously
* added resources, unless they were marked <a href="#Final">final</a>.
*
* @param name resource to be added, the classpath is examined for a file
* with that name.
*/
/**
* 添加新的配置资源
* 该资源配置将会覆盖之前添加的资源配置----除非该配置项被final,参数路径是相对CLASSPATH而言的
*/
public void addResource(String name) {
addResourceObject(new Resource(name));
}
public void addResource(String name, boolean restrictedParser) {
addResourceObject(new Resource(name, restrictedParser));
}
//把资源添加进resource中
private synchronized void addResourceObject(Resource resource) {
resources.add(resource); // add to resources
restrictSystemProps |= resource.isParserRestricted();
reloadConfiguration();
}
//清空之前的所有properties中与finalParameters中的配置
public synchronized void reloadConfiguration() {
properties = null; // trigger reload
finalParameters.clear(); // clear site-limits
}
2)默认配置文件的加载
简单来说,Configuration类在在加载的时候,
core-default.xml
和core-default.xml
已经被加载
static{
//print deprecation warning if hadoop-site.xml is found in classpath
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");
}
// 添加默认配置到defaultResources中,然后清空非默认配置
public static synchronized void addDefaultResource(String name) {
if(!defaultResources.contains(name)) {
defaultResources.add(name);
for(Configuration conf : REGISTRY.keySet()) {
if(conf.loadDefaults) {
// 清空 finalParameters与properties
conf.reloadConfiguration();
}
}
}
}
5.配置对象的注册:
/** A new configuration. */
public Configuration() {
this(true);
}
/**
* 默认会加载默认的资源配置文件中的配置
* REGISTRY用来注册新的Configuration的新实例
*/
public Configuration(boolean loadDefaults) {
this.loadDefaults = loadDefaults;
updatingResource = new ConcurrentHashMap<String, String[]>();
synchronized(Configuration.class) {
REGISTRY.put(this, null);
}
}