Hadoop源码解析 2 --- Hadoop配置文件解析

1 Hadoop Configuration简介
    Hadoop没有使用java.util.Properties管理配置文件,
也没有使用Apache Jakarta Commons
Configuration管理配置文件,而是使用了一套独有的配置文件管理系统,并提供自己的API,即使用
org.apache.hadoop.conf.Configuration处理配置信息。

org.apache.hadoop.conf目录结构如下:

2 Hadoop配置文件的格式解析
    Hadoop配置文件采用XML格式,下面是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一般不出现,但在合并资源的时候,可以防止配置项的值被覆盖。
    在
上面的示例文件中,配置项dfs.web.ugi的值是“webuser,webgroup”,它是一个final配置项;从description看,
这个配置项配置了Hadoop Web界面的用户账号,包括用户名和用户组信息。这些信息可以通过Configuration类提供的方法访问。
    在
Configuration中,每个属性都是String类型的,但是值类型可能是以下多种类型,包括Java中的基本类型,如
boolean(getBoolean)、int(getInt)、long(getLong)、float(getFloat),也可以是其他类型,如
String(get)、java.io.File(getFile)、String数组(getStrings)等。以上面的配置文件为
例,getInt("io.sort.factor")将返回整数10;而getStrings("dfs.web.ugi")返回一个字符串数组,该数
组有两个元素,分别是webuser和webgroup。
    合并资源指将多个配置文件合并,产生一个配置。如果有两个配置文件,也就是两个资源,如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,那么,在加载第二个资源的时候,会有警告提示。

3 直接运行Configuration.java则会调用默认配置文件部分结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<property>
<name>ipc.client.fallback-to-simple-auth-allowed</name>
<value>false</value>
<source>core-default.xml</source>
</property>
<property>
<name>file.bytes-per-checksum</name>
<value>512</value>
<source>core-default.xml</source>
</property>
<property>
<name>ipc.server.tcpnodelay</name>
<value>false</value>
<source>core-default.xml</source>
</property>
<property>
<name>ftp.client-write-packet-size</name>
<value>65536</value>
<source>core-default.xml</source>
</property>
<property>
<name>nfs3.mountd.port</name>
<value>4272</value>
<source>core-site.xml</source>
</property>
</configuration>

4 我们一般在wordcount程序中使用Configuration的set函数来添加或修改相关配置项,下面通过这种途径解析其具体实现方式

4.1 Configuration conf = new Configuration(true)的具体实现如下(见4.1.2):

Configuration有3个构造函数:

4.1.1 如果在新建Configuration对象时无参数,则系统默认调用该构造函数

    public Configuration() {
this(true);
}

4.1.2 如果在新建Configuration对象时有boolean类型形参,则调用该构造函数

    /**
* 1 新建一个Configuration类,如果loadDefaults=false,
* 则新建的Configuration实例默认不会加载默认的配置文件
*/
public Configuration(boolean loadDefaults) {
System.out.println("Configuration(boolean loadDefaults)");
this.loadDefaults = loadDefaults;// 选择是否加载默认配置文件,false为不加载,true加载
System.out.println("loadDefaults: " + loadDefaults);
updatingResource = new HashMap<String, String[]>();// 保存修改过的配置项
synchronized (Configuration.class) {
REGISTRY.put(this, null);
}
}

4.1.3 如果在新建Configuration对象时有Configuration类型形参,则调用该构造函数

    /**
*
* @param 调用其它Configuration对象的配置文件
*/
@SuppressWarnings("unchecked")
public Configuration(Configuration other) {
this.resources = (ArrayList<Resource>) other.resources.clone();
synchronized (other) {
if (other.properties != null) {
this.properties = (Properties) other.properties.clone();
} if (other.overlay != null) {
this.overlay = (Properties) other.overlay.clone();
} this.updatingResource = new HashMap<String, String[]>(
other.updatingResource);
} this.finalParameters = new HashSet<String>(other.finalParameters);
synchronized (Configuration.class) {
REGISTRY.put(this, null);
}
this.classLoader = other.classLoader;
this.loadDefaults = other.loadDefaults;
setQuietMode(other.getQuietMode());
}

4.2 conf.set("fs.defaultFS", "file///");

set函数有:

public void set(String name, String value, String source)

public void set(String name, String value)

public synchronized void setIfUnset(String name, String value)

public void setInt(String name, int value)

public void setLong(String name, long value)

public void setFloat(String name, float value)

public void setDouble(String name, double value)

public void setBoolean(String name, boolean value)

public void setBooleanIfUnset(String name, boolean value)

public <T extends Enum<T>> void setEnum(String name, T value)

public void setTimeDuration(String name, long value, TimeUnit unit)

public void setPattern(String name, Pattern pattern)

public void setStrings(String name, String... values)

public void setStrings(String name, String... values)

public void setClass(String name, Class<?> theClass, Class<?> xface)

其中,后面的set相关函数都是调用第一个set函数实现,下面就具体解析一下public void set(String name, String value, String source)

    /**
*
* @Title set
* @Description 将参数name对应的value存入property中,如果该name在property中存在则覆盖,否则添加
* @param
* @return
* @throws
*/
public void set(String name, String value, String source) {
System.out.println("set(name, value, source) start !"); Preconditions.checkArgument(name != null, "Property name must not be null");
Preconditions.checkArgument(value != null, "The value of property " + name + " must not be null");
DeprecationContext deprecations = deprecationContext.get();//保存不在配置文件的key
System.out.println("deprecations: "+deprecations);
System.out.println("deprecations.getDeprecatedKeyMap().isEmpty(): "+deprecations.getDeprecatedKeyMap().isEmpty());
if (deprecations.getDeprecatedKeyMap().isEmpty()) {
getProps();
} getOverlay().setProperty(name, value);
getProps().setProperty(name, value);
String newSource = (source == null ? "programatically" : source); System.out.println("newSource: " + newSource);
if (!isDeprecated(name)) {//检测该name(key)项是否在配置文件中存在 System.out.println("!isDeprecated(name): " + !isDeprecated(name)); updatingResource.put(name, new String[] { newSource });//将该name(key)项参数添加进updatingResource中,说明该项已被修改
String[] altNames = getAlternativeNames(name);//判断该name(key)是否在默认配置文件中存在,如果存在则将name存入altNames中 /**
* 如果name(key)则默认配置文件中存在,则将name对应value存入updatingResource
*/
if (altNames != null) {
for (String n : altNames) {
System.out.println("altNames: "+n);
if (!n.equals(name)) {
getOverlay().setProperty(n, value);
getProps().setProperty(n, value);
updatingResource.put(n, new String[] { newSource });
}
}
}
} else {
String[] names = handleDeprecation(deprecationContext.get(), name);
String altSource = "because " + name + " is deprecated";
for (String n : names) { System.out.println("names: "+names); getOverlay().setProperty(n, value);
getProps().setProperty(n, value);
updatingResource.put(n, new String[] { altSource });
}
}
}

5 Configuration测试程序如下:

/**
* @Title ConfigurationTest.java
* @Package org.apache.hadoop.conftest
* @Description TODO
* @date 2014年9月11日 上午11:27:14
* @version V1.0
*/
package org.apache.hadoop.conftest; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path; public class ConfigurationTest {
public static void main(String args[]){
Configuration conf = new Configuration(true);
Path hadoop_mapred = new Path("hadoop-2.3.0/etc/hadoop/mapred-site.xml");
Path hadoop_yarn = new Path("hadoop-2.3.0/etc/hadoop/yarn-site.xml");
conf.addResource(hadoop_mapred);
conf.addResource(hadoop_yarn);
conf.set("mapreduce.jobtracker.system.dir", "file:///data1");//this conf can change the same parameter in the mapred-site.xml when the paramter is used
conf.setInt("test1", 10);//This parameter will be add to property due to it not in the properties
conf.set("fs.defaultFS", "file///data");//This parameter will change the same parameter value in the properties
System.out.println(conf.get("test1"));
System.out.println(conf.get("mapreduce.jobtracker.system.dir"));
System.out.println(conf.get("yarn.resourcemanager.admin.address"));
System.out.println("ok");
}
}

  原创文章欢迎转载,转载时请注明出处。

  作者推荐文章:

    》Java自学之道

    》总结5种比较高效常用的排序算法

    》如何获取系统信息

    》如何生成二维码过程详解

    百度云盘下载地址 http://pan.baidu.com/s/1eQzSiEA

Hadoop配置文件解析的更多相关文章

  1. MyBatis配置文件解析

    MyBatis配置文件解析(概要) 1.configuration:根元素 1.1 properties:定义配置外在化 1.2 settings:一些全局性的配置 1.3 typeAliases:为 ...

  2. Nginx安装与配置文件解析

    导读 Nginx是一款开放源代码的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3代理服务,是一款自由的软件,同时也是运维工程师必会的一种服务器,下面我就简单的说一下Nginx服务器的 ...

  3. Python3 配置文件 解析

    /************************************************************************ * Python3 配置文件 解析 * 说明: * ...

  4. Hibernate的配置文件解析

    配置mybatis.xml或hibernate.cfg.xml报错: <property name="connection.url">jdbc:mysql://loca ...

  5. WCF中配置文件解析

    WCF中配置文件解析[1] 2014-06-14 WCF中配置文件解析 参考 WCF中配置文件解析 返回 在WCF Service Configuration Editor的使用中,我们通过配置工具自 ...

  6. haproxy之配置文件解析

    功能--> 提供高可用/负载均衡/基于tcp和http应用的代理;支持虚拟主机,特别适用于负载特大的web站点. 配置文件解析--> #配置文件-->开启/proc/net/ipv4 ...

  7. nginx源代码分析--配置文件解析

    ngx-conf-parsing 对 Nginx 配置文件的一些认识: 配置指令具有作用域,分为全局作用域和使用 {} 创建其他作用域. 同一作用域的不同的配置指令没有先后顺序:同一作用域能否使用同样 ...

  8. ZooKeeper介绍,安装,配置文件解析

    什么是ZooKeeper? ZooKeeper是用于维护配置信息,命名,提供分布式同步和提供组服务的集中式服务. 所有这些类型的服务都以分布式应用程序以某种形式或另一种形式使用.每次实施时,都有很多工 ...

  9. Spring Security 入门(1-6-1)Spring Security - 配置文件解析和访问请求处理

    1.在pom.xml中添加maven坐标 <dependency> <groupId>org.springframework.security</groupId> ...

随机推荐

  1. Java for LeetCode 031 Next Permutation

    Next Permutation Total Accepted: 33595 Total Submissions: 134095     Implement next permutation, whi ...

  2. ShortestPath:Wormholes(POJ 3259)

    田里的虫洞 题目大意:就是这个农夫的田里有一些虫洞,田有很多个点,点与点之间会存在路,走过路需要时间,并且这些点存在虫洞,可以使农夫的时间退回到时间之前,问你农夫是否真的能回到时间之前? 读完题:这一 ...

  3. [Linux] AWK命令详解(大全)

    转载自:http://caoyanbao.iteye.com/blog/570868 什么是awk? 你可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk ...

  4. Vigenère 密码(luogu 1079)

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  5. Spell checker(poj 1035)

    题意:     此题是一个字符串的问题,首先要给出一个字典,里面存储了数个单词.而后,给出一个单词,如果字典中存在,那么就输出correct,如果字典中没有,那么就要判断是不是这个单词有错误,错误有3 ...

  6. centos7下yum安装mysql

    CentOS 7的yum源中貌似没有正常安装mysql时的mysql-sever文件,需要去官网上下载   # wget http://dev.mysql.com/get/mysql-communit ...

  7. Android 4.0 事件输入(Event Input)系统

    参考:http://blog.csdn.net/myarrow/article/details/7091061 1. TouchScreen功能在Android4.0下不工作 原来在Android2. ...

  8. java类加载时机与过程

    转自:http://www.tuicool.com/articles/QZnENv 说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要 ...

  9. php截取指定字符串之间的字符串的类

    一个php截取指定字符串之间的字符串的类 <?php   class get_c_str {   var $str;   var $start_str;   var $end_str;   va ...

  10. SQL Server2008跟SQL Server2008R2的区别(转)

    QL Server 2008 R2基于SQL Server 2008提供可靠高效的智能数据平台构建而成,SQL Server 2008 R2 提供了大量新改进,可帮助您的组织满怀信心地调整规模.提高 ...