文档章节

hadoop-common源码分析之-Configuration

呆萌的我
 呆萌的我
发布于 2015/10/13 20:13
字数 1355
阅读 50
收藏 0

Configuration类实现了Iterable、Writable接口,使得可以遍历和序列化(hadoop自己序列化)

配置文件格式

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>lala</name>
        <value>${user.home}/hadoopdata</value>
        <final>true</final>
    </property>
</configuration>

hadoop是通过xml进行配置的,同时支持属性扩展,user.home当调用get的时候,会首先通过System.getProperty()判断是否是系统参数,例中${user.home}就被替换成当前用户的path。所以,当我们在配置hadoop时,可以直接用一些系统属性,增强可移植性。
当一个属性被生命为final时,后面添加配置,不会覆盖先加在的配置。
同时,因为使用的是java的DOM解析,所以支持XML的包涵,在配置文件中可以用<xi:include href="" />来分类管理。

代码分析

私有内部类Resource

  private static class Resource {
  //私有内部类,标记资源名字和资源对象
    private final Object resource;
    private final String name;
    ...
    }

私有内部类DeprecatedKeyInfo、DeprecationDelta、DeprecationContext

  private static class DeprecatedKeyInfo {
    private final String[] newKeys;
    private final String customMessage;
    private final AtomicBoolean accessed = new AtomicBoolean(false);
    private final String getWarningMessage(String key) {
     }
  }

  public static class DeprecationDelta {
    private final String key;
    private final String[] newKeys;
    private final String customMessage;
  }

  private static class DeprecationContext {
    //存放oldkey-newkeys
    private final Map<String, DeprecatedKeyInfo> deprecatedKeyMap;
    //存放newkeys-oldkey,提供反查功能
    private final Map<String, String> reverseDeprecatedKeyMap;
    DeprecationContext(DeprecationContext other, DeprecationDelta[] deltas) {
    ...
    this.deprecatedKeyMap = UnmodifiableMap.decorate(newDeprecatedKeyMap);
    this.reverseDeprecatedKeyMap =UnmodifiableMap.decorate(newReverseDeprecatedKeyMap);
    }
  }

DeprecatedKeyInfo保存了新的key和信息,如果customMessage为空,在调用getWarningMessage会自动生成默认的信息。
DeprecationDelta 保存了被遗弃的key 和 建议用的新key。
DeprecationContext封装讲被遗弃的key和推荐使用的keys、提示封装在一起。

  private static AtomicReference<DeprecationContext> deprecationContext =
      new AtomicReference<DeprecationContext>(
          new DeprecationContext(null, defaultDeprecations));

一个全局的DeprecationContext对象,原子的,并且将默认被遗弃的key加载进去。

静态addDeprecations方法

值得一提的是此方法很巧妙的使用无锁的方法,但是,保证了数据的安全性,看具体代码:

  public static void addDeprecations(DeprecationDelta[] deltas) {
    DeprecationContext prev, next;
    do {
      prev = deprecationContext.get();
      next = new DeprecationContext(prev, deltas);
    } while (!deprecationContext.compareAndSet(prev, next));
  }

compareAndSet方法是当前对象和prev相等(==)时,更新当前对象为next

setDeprecatedProperties

分析源码,我们发现,setDeprecatedProperties的作用就是为了更新overlay和properties,使得,我们在获得key时,能得到最新的状态,看下面例子:

  configuration.addDeprecation("xx", new String[]{"xx1","xx2","xx3"});
  //configuration.setDeprecatedProperties();
  System.out.println(configuration.get("xx"));

当注释掉configuration.setDeprecatedProperties后,我get时,获得的事null值,所以我们要遍历已经被遗弃的key时,需要更新setDeprecatedProperties,可以使得被遗弃的key依旧可以被使用。

handleDeprecation

首先判断该key是否是被遗弃的,如果是,将得到建议用的key,否则更新overlay、properties,并返回建议使用的key数组。

用样handleDeprecation方法是,执行刷新操作。具体用在asXmlDocument中。

static{}静态代码块

分析代码我们可以得到一下几点:

  1. 如果在classpath下存在hadoop-site.xml,会log4j会打印警告信息,没有加载到defaultResources。
  2. 默认加载两个核心配置文件core-default.xml、core-site.xml

addResourceObject以及若干方法

不管用何种addResource,最终都是调用了addResourceObject(Resource resource),他首先将资源添加到一个全局的List集合,然后调用reloadConfiguration来触发刷新properties并且标记为final的key失效。

findSubVariable substituteVars

在hadoop-2.7之前,只有一个substituteVars方法,使用java自身的正则表达式来匹配获得${user.home }中间的值(user.home)。

hadoop-2.7版本之后,为了提升性能,自己实现了匹配获取中间值的方法( findSubVariable ) ps:可能是因为,由于java自身的正则表达式方式过于消耗性能,所以,通过自己手动匹配,降低性能的消耗。

  //此方法,将字符串中${}中间的位置的区间获取到,详细看代码
  private static int[] findSubVariable(String eval) {
        ...
 }
  //1.将获取key进行替换,如果System.getProperty()存在,替换
  //2.不存在,查找properties,如果存在替换,不存在,原样保留
  private String substituteVars(String expr) {
    ...
  }

set方法

  //通过程序设置key-value,source允许为空,当用户不设置源时,程序自动将programatically这是为source,
  //当值为被遗弃的,此方法会先将新key的到,并设置source为 because old key is deprecated
 public void set(String name, String value, String source) {
     ...
 }

loadResource

该方法是解析xml的,采用了DOM解析,分析代码我们知道,xml格式需要和上面写到的格式,同时DOM解析,支持xml文件引入。

和以前版本相比,xml配置文件中,在property中可以声明source标签,声明资源的信息?

 if ("source".equals(field.getTagName()) && field.hasChildNodes())
  source.add(StringInterner.weakIntern(
      ((Text)field.getFirstChild()).getData()));

hadoop还提供了一些方法,如,asXmlDocument等,不一一分析,不知道源码分析文章应该怎么写,我觉得还是要自己先读源码,看不懂的过来参考,由于此类有3000多行,不太方便阅读,理解错的地方还请各位指出一起探讨。

总结:

1.配置hadoop的时候,用${user.home}来换成当前用户目录是不是很高大上呢。

2.再配置xml中2.7版本增加了解析source标签,可以存储源的信息,具体在后续源码分析中,在研究它的作用

3.设计的很巧妙,处处为了性能着想啊,还要好好分析剩下源码,等全部分析完成后,再来续写此文章。

版权声明:本文为博主原创文章,未经博主允许不得转载。

© 著作权归作者所有

呆萌的我
粉丝 4
博文 15
码字总数 15443
作品 0
天津
私信 提问
加载中

评论(1)

pacman
pacman
0
hadoop2.2.0源代码编译

一、环境说明 虚拟软件:VMware Workstation 10 虚拟机配置: RHEL Server release 6.5 (Santiago) 2.6.32-431.el6.x86_64 cpu:4核心,内存:4G,硬盘:50G 二、前提条件: 1:将rhel6.5的iso文件作为...

cloud-coder
2014/01/11
5K
6
Eclipse连接Hadoop分析的三种方式

Hadoop一般都部署在linux平台上,想让Hadoop执行我们写好的程序,首先需要在本地写好程序打包,然后上传到liunx,最后通过指定命令执行打包好的程序;一次两次还可以,如果进行频繁的调试是很...

ksfzhaohui
2016/10/27
2.4K
0
HDFS + WEB 项目 报java.lang.VerifyError... 异常

今天在用web项目整合 HDFS 的时候发生了非常诡异的事情。我将java项目的HDFS功能整合至 web项目的时候创建FileSystem对象就报Exception in thread "main" java.lang.VerifyError: (class: c...

霖_柒
2015/12/08
555
0
2018-07-07期 Hadoop本地运行模式配置 【本人整合多方资料并亲自反复验证通过分享】

详细来源:05-Hadoop本地运行模式配置 在Windows开发环境中实现Hadoop的本地运行模式,详细步骤如下: 1、在本地安装好jdk、hadoop2.4.1,并配置好环境变量:JAVAHOME、HADOOPHOME、Path路径...

JackmaSong
2018/07/07
0
0
win7搭建为伪分布式hadoop

window7下安装hadoop [32位] 1.下载hadoop hadoop-2.2.0.tar.gz 解压 2.配置环境变量hadoop 3.修改%HADOOP_HOME%etchadoop的hadoop-env.sh export JAVA_HOME=D:Javajdk1.6.0_10#不能有空格 ......

泡海椒
2016/02/27
41
1

没有更多内容

加载失败,请刷新页面

加载更多

浅谈Visitor访问者模式

一、前言 什么叫访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+对其进行处理就叫作访问,那么...

青衣霓裳
31分钟前
6
0
JS内嵌多个页面,页面之间如何更快捷的查找相关联的页面

假设parent为P页面, P页面有两个子页面,分别为B页面和C页面; B页面和C页面分别内嵌一个iframe,分别为:D页面和E页面 现在通过B页面的内嵌页面D的方法refreshEpage(eUrl)来加载内嵌页面E的内容...

文文1
32分钟前
7
0
Hibernate 5 升级后 getProperties 错误

升级到 Hibernate 5 后,提示有错误: org.hibernate.engine.spi.SessionFactoryImplementor.getProperties()Ljava/util/Map; 完整的错误栈为: java.lang.NoSuchMethodError: org.hibernate......

honeymoose
34分钟前
6
0
mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
37分钟前
7
0
Spring中BeanFactory与FactoryBean的区别

在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混。 一、BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定...

大王叫下
39分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部