Hadoop源码学习笔记(1)

——找到Main函数及读一读Configure类

前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用。在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的。

提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的。欢迎高手指正。

整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了。

在之前源码初窥中,我们已经找到了主要几个的main函数入口。所以这里我们列一列计划:

  1. FsShell main入口: org.apache.hadoop.fs.FsShell
  2. NameNode main入口: org.apache.hadoop.hdfs.server.namenode.NameNode
  3. DataNode main入口: org.apache.hadoop.hdfs.server.datanode.DataNode
  4. JobTracker main入口: org.apache.hadoop.mapred.JobTracker
  5. TaskTracker main入口: org.apache.hadoop.mapred.TaskTracker

我们会按这个顺序来研究,至于其他的像SecondeNameNode之类的,在最后再来研究。

同样,针对这些内容,我们还会分一下,第一步先来看DFS,第二步再来看MapReduce部份。

在研究DFS之前,我们看一下,这三者关系:

其中NameNode是客户端的主接口,也是唯一的对接点,同时主要负责文件名目录管理,以及数据DataNode的映射。

好了,要研究一块,我们先来把程序跑起来吧。

在eclipse中我们很方便地就能找到每个模块的对应的main函数,但还是有些不便,为了调试方便,我们再新建三个入口类:

自建入口类主要是为方便找到,然后这三个类中的代码分别为:

FsShellEnter.java

  1. import org.apache.hadoop.fs.FsShell;
  2.  
  3. public class FsShellEnter {
  4.  
  5.    public static void main(String[] args) throws Exception {
  6.       FsShell.main(new String[]{"-ls"});
  7.    }
  8. }

NamNodeEnter.java

  1. public class NameNodeEnter {
  2.  
  3.    public static void main(String[] args) throws Exception {
  4.       org.apache.hadoop.hdfs.server.namenode.NameNode.main(args);
  5.    }
  6. }

DataNodeEnter.java

  1. public class DataNodeEnter {
  2.  
  3.    public static void main(String[] args) {
  4.       org.apache.hadoop.hdfs.server.datanode.DataNode.main(args);
  5.    }
  6. }

运行之:

启动命令行,运行:$ bin/hadoop namenode

然后在eclipse中,打开FsShellEnter.java,然后点击运行,可以看到:

反过来,在eclipse中,打开NamNodeEnter.java,点击运行,

在控制台中,可以输入一堆的信息,说明正常了。

然后打开命令行,输入:$ bin/hadoop fs -ls,可以看到:

这样,说明正反运行都可以了。

当然这里我们没有涉及文件内容操作,所以没有DataNode也没问题,不过可以自行试一下。

打开这几个main函数,都可以看到上来都在初使化这个Configuration类。所以我们先来看一看这个类到底有点啥:

先看一下之前我们如何用这个类的:

  1. Configuration conf = new Configuration();
  2. String name = conf.get("fs.default.name");
  3. System.out.println(name);

从字面意思及这段函数,可以看出Configuration类用于读取配置文件的,且该程序就是读出配置文件中fs.default.name的值。

观察其构造函数:

  1. public Configuration() {
  2.     this(true);
  3. }
  4.  public Configuration(boolean loadDefaults) {
  5.     this.loadDefaults = loadDefaults;
  6.     if (LOG.isDebugEnabled()) {
  7.       LOG.debug(StringUtils.stringifyException(new IOException("config()")));
  8.     }
  9.     synchronized(Configuration.class) {
  10.       REGISTRY.put(this, null);
  11.     }
  12.   }

发现其本没有做什么操作,主要设置了一个loadDefaults值为true。

然后再观察get函数:

  1.   public String get(String name) {
  2.     return substituteVars(getProps().getProperty(name));
  3.   }
  4. private synchronized Properties getProps() {
  5.     if (properties == null) {
  6.       properties = new Properties();
  7.       loadResources(properties, resources, quietmode);
  8.       if (overlay!= null)
  9.         properties.putAll(overlay);
  10.     }
  11.     return properties;
  12.   }

Get函数先是调用了substituteVars函数,这个是正则表达式处理函数,对返回值进行去非法字符处理,然后getProps函数中,对hashtable类型的properties进行判断,如果为空则创建并进行初使化,否则直接返回。然后getProperty再根据其key值进行取值。

很明显,这里是采用了懒加载的方式,就是说并没有一开始加载配置文件中的数据,而是等要访问时,才进行加载。

进一步看如何初使化的,loadResources函数:

  1. private void loadResources(Properties properties,
  2.                              ArrayList resources,
  3.                              boolean quiet) {
  4.     if(loadDefaults) {
  5.       for (String resource : defaultResources) {
  6.         loadResource(properties, resource, quiet);
  7.       }
  8.  
  9.       //support the hadoop-site.xml as a deprecated case
  10.       if(getResource("hadoop-site.xml")!=null) {
  11.         loadResource(properties, "hadoop-site.xml", quiet);
  12.       }
  13.     }
  14.  
  15.     for (Object resource : resources) {
  16.       loadResource(properties, resource, quiet);
  17.     }
  18.   }

这里第5行可看到先加载了defaultResources中的资源,然后再加载hadoop-site.xml(第10行)。

defaultResources有哪些呢,一步步找,可以看到:

  1. static{
  2.    ...
  3.     addDefaultResource("core-default.xml");
  4.     addDefaultResource("core-site.xml");
  5.   }
  6.  public static synchronized void addDefaultResource(String name) {...}

从这里看到,默认加载了core-default.xml和core-site.xml这两个文件。

到这里,我们可以再打开这3个XML来看看了:

从这两个文件,我们可以看出,配置文件中存储就是用的key-value的健值对方式,然后加一个description对该配置项的描述。所以程序中读取也是传入key即可获取value。

同时,core-site.xml是我们自己配置文件,仔细看,可发现,在core-defalut.xml中也有一些相同的配置项。加载时先加载defalut再site,后者有相同key时覆盖前者。

所以换句话说,我们可以不配置hadoop.tmp.dir 则默认就在上面default中的/tmp….目录。

同时也可相到,hadoop的其他配置,就可以参考core-default.xml中的了。 可以直接改,也可以在core-site中再复制一份再改。

继续观察Configuration还有哪些方法:

发现其中有很多个get函数,然后是返回各种不同类型的。这样就方便我们取值后直接处理了。

同时,可以看到还有一堆的set函数。这些set函数追进去看,是在修改hashtable的,并没有保存。所以说这些用途也是可见的,不用配置文件也可以让Configuration工作起来。

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类的更多相关文章

  1. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  2. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  3. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  4. Hadoop源码学习笔记(3) ——初览DataNode及学习线程

    Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...

  5. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  6. Hadoop源码学习笔记之NameNode启动场景流程一:源码环境搭建和项目模块及NameNode结构简单介绍

    最近在跟着一个大佬学习Hadoop底层源码及架构等知识点,觉得有必要记录下来这个学习过程.想到了这个废弃已久的blog账号,决定重新开始更新. 主要分以下几步来进行源码学习: 一.搭建源码阅读环境二. ...

  7. Hadoop源码学习笔记之NameNode启动场景流程四:rpc server初始化及启动

    老规矩,还是分三步走,分别为源码调用分析.伪代码核心梳理.调用关系图解. 一.源码调用分析 根据上篇的梳理,直接从initialize()方法着手.源码如下,部分代码的功能以及说明,已经在注释阐述了. ...

  8. Hadoop源码学习笔记之NameNode启动场景流程五:磁盘空间检查及安全模式检查

    本篇内容关注NameNode启动之前,active状态和standby状态的一些后台服务及准备工作,即源码里的CommonServices.主要包括磁盘空间检查. 可用资源检查.安全模式等.依然分为三 ...

  9. Hadoop源码学习笔记之NameNode启动场景流程二:http server启动源码剖析

    NameNodeHttpServer启动源码剖析,这一部分主要按以下步骤进行: 一.源码调用分析 二.伪代码调用流程梳理 三.http server服务流程图解 第一步,源码调用分析 前一篇文章已经锁 ...

随机推荐

  1. Eclipse导出JAR过程

    Eclipse是一款免费的JAVA开发环境,被各个软件公司使用,可以说是目前使用最多的JAVA开发工具了,网址:http://www.eclipse.org 下面演示如何建立JAVA工程和导出JAR: ...

  2. linux命令之文件备份与压缩命令

    1.tar:打包备份 该命令是将多个命令打包到一起,并且可以实现解压打包.打包是将多个文件或者目录变成一个总的文件,压缩则是将一个大的文件通过压缩算法变成一个小文件. 参数 说明 z(常用) 通过gz ...

  3. 在线编辑器Ckeditor (1) - php (30)

    在线编辑器 在线编辑器也称之为所见即所得编辑器,是一种常见的html源码编辑器. 所见即所得:用户在输入的时候,不论是格式和是样式都能被系统原封不动的保存,最后在查看的时候,可以按照用户输入的原来的结 ...

  4. “全栈2019”Java第九十七章:在方法中访问局部内部类成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. vue 中的computed和watch

    计算属性 通过计算得来的属性 computed:是一个计算属性,用来监听属性的变化 computed里面的方法调用的时候是不需要加() 另外里面的方法必须要有一个返回值   computed里面的方法 ...

  6. mxonline实战10,课程列表页,课程详情页1

    对应github地址:第10天   一. 课程列表页   1. 拷贝course-list.html到templates目录中 2. 编写url和view 在courses/views.py中新加

  7. 终于搞定在VS2010中将CString转换为const char*

    最近碰到了CString 转 const char *的问题. 以前只要简单的一个强制转换就OK了,可现在是不行了,搜索了很多资料,终于搞定,主要是Unicode和ANSI的问题,只要做一个转换就可以 ...

  8. QuantLib 金融计算——随机过程之 Heston 过程

    目录 QuantLib 金融计算--随机过程之 Heston 过程 Heston 过程 参考文献 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--随机过程之 H ...

  9. Windows Server2008如何打开添加IIS服务器

    https://jingyan.baidu.com/article/1612d500aa4594e20e1eeefc.html

  10. 用Python写了一个postgresql函数,感觉很爽

    用Python写了一个postgresql函数,感觉很爽 CREATE LANGUAGE plpythonu; postgresql函数 CREATE OR REPLACE FUNCTION myfu ...