Hadoop2.6.0子项目hadoop-mapreduce-examples的简单介绍

简介: 学习Hadoop的同学们,一定知道如果运行Hadoop自带的各种例子。hadoop-mapreduce-examples项目中还提供了这些例子,本文就其中例子的执行方式进行分析。看看它能否让我们学习mapreduce编程变得更加容易。

引文

学习Hadoop的同学们,一定知道如果运行Hadoop自带的各种例子,以大名鼎鼎的wordcount为例,你会输入以下命令:

hadoop org.apache.hadoop.examples.WordCount -D mapreduce.input.fileinputformat.split.maxsize=1 /wordcount/input /wordcount/output/result1
AI 代码解读

当然,有些人还会用以下替代方式:

hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar wordcount /wordcount/input /wordcount/output/result1
AI 代码解读

相比于原始的执行方式,使用jar命令方式,让我们不用再敲入繁琐的完整包路径。比如我们知道hadoop-mapreduce-examples项目中还提供了其它的例子,比如计算圆周率的例子,我们只需要记住此应用的简单名字pi,就可以执行它:

hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar pi 5 10
AI 代码解读

虽说我们只是使用这些现成的例子,没有必要较真,但是这种简洁的使用方式,无疑还是值得借鉴的。本文将分析下这种方式实现的原理,有兴趣的同学可以一读。

源码分析

这一节,我们通过对hadoop-mapreduce-examples项目中的关键源码进行分析,理解简洁执行的原理。在hadoop-mapreduce-examples项目的pom.xml文件中配置了org.apache.hadoop.examples.ExampleDriver作为jar命令的入口,配置如下:

   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-jar-plugin</artifactId>
      <configuration>
       <archive>
         <manifest>
           <mainClass>org.apache.hadoop.examples.ExampleDriver</mainClass>
         </manifest>
       </archive>
     </configuration>
    </plugin>
AI 代码解读

这决定了使用jar命令执行hadoop-mapreduce-examples-2.6.0.jar包时,实际执行了ExampleDriver的main方法,ExampleDriver的实现如下:

public class ExampleDriver {
  
  public static void main(String argv[]){
    int exitCode = -1;
    ProgramDriver pgd = new ProgramDriver();
    try {
      pgd.addClass("wordcount", WordCount.class, 
                   "A map/reduce program that counts the words in the input files.");
      // 省略其它例子的注册代码
      pgd.addClass("pi", QuasiMonteCarlo.class, QuasiMonteCarlo.DESCRIPTION);
      // 省略其它例子的注册代码
      exitCode = pgd.run(argv);
    }
    catch(Throwable e){
      e.printStackTrace();
    }
    
    System.exit(exitCode);
  }
}
AI 代码解读

以上代码构造了ProgramDriver的实例,并且调用其addClass方法,三个参数分别是例子名称(如wordcount、pi等)、例子的实现Class、例子的描述信息。ProgramDriver的addClass方法的实现如下:

  public void addClass(String name, Class<?> mainClass, String description)
      throws Throwable {
    programs.put(name , new ProgramDescription(mainClass, description));
  }
AI 代码解读

首先,构造ProgramDescription对象,其构造函数如下:

    public ProgramDescription(Class<?> mainClass, 
                              String description)
      throws SecurityException, NoSuchMethodException {
      this.main = mainClass.getMethod("main", paramTypes);
      this.description = description;
    }
AI 代码解读

其中main的类型是java.lang.reflect.Method,用于保存例子Class的main方法。
然后,将例子名称(如wordcount、pi等)和ProgramDescription实例注册到programs中,programs的类型定义如下:

  /**
   * A description of a program based on its class and a 
   * human-readable description.
   */
  Map<String, ProgramDescription> programs;
AI 代码解读

ExampleDriver的main方法在最后会调用ProgramDriver的run方法,其实现如下:

  public int run(String[] args)
    throws Throwable 
  {
    // Make sure they gave us a program name.
    if (args.length == 0) {
      System.out.println("An example program must be given as the" + 
                         " first argument.");
      printUsage(programs);
      return -1;
    }
    
    // And that it is good.
    ProgramDescription pgm = programs.get(args[0]);
    if (pgm == null) {
      System.out.println("Unknown program '" + args[0] + "' chosen.");
      printUsage(programs);
      return -1;
    }
    
    // Remove the leading argument and call main
    String[] new_args = new String[args.length - 1];
    for(int i=1; i < args.length; ++i) {
      new_args[i-1] = args[i];
    }
    pgm.invoke(new_args);
    return 0;
  }
AI 代码解读

ProgramDriver的run方法执行的步骤如下:

  1. 参数长度校验;
  2. 根据第一个参数,从programs中查找对应的ProgramDescription实例;
  3. 将其余的参数传递给ProgramDescription的invoke方法,进而执行对应的例子。
    ProgramDescription的invoke方法的实现如下:
    public void invoke(String[] args)
      throws Throwable {
      try {
        main.invoke(null, new Object[]{args});
      } catch (InvocationTargetException except) {
        throw except.getCause();
      }
    }
AI 代码解读

由此我们知道具体例子的执行,是通过反射调用具体例子Class的main方法,最终实现的。

后记:个人总结整理的《深入理解Spark:核心思想与源码分析》一书现在已经正式出版上市,目前京东、当当、天猫等网站均有销售,欢迎感兴趣的同学购买。
_

京东(现有满150减50活动)):http://item.jd.com/11846120.html
当当:http://product.dangdang.com/23838168.html

目录
打赏
0
0
0
0
60
分享
相关文章
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
101 2
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
150 3
Hadoop-06-Hadoop集群 历史服务器配置 超详细 执行任务记录 JobHistoryServer MapReduce执行记录 日志聚合结果可视化查看
Hadoop-06-Hadoop集群 历史服务器配置 超详细 执行任务记录 JobHistoryServer MapReduce执行记录 日志聚合结果可视化查看
71 1
Hadoop-05-Hadoop集群 集群WordCount 超详细 真正的分布式计算 上传HDFS MapReduce计算 YRAN查看任务 上传计算下载查看
Hadoop-05-Hadoop集群 集群WordCount 超详细 真正的分布式计算 上传HDFS MapReduce计算 YRAN查看任务 上传计算下载查看
77 1
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
369 2
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
155 0
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
68 0
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
87 0
优化Hadoop MapReduce性能的最佳实践
【8月更文第28天】Hadoop MapReduce是一个用于处理大规模数据集的软件框架,适用于分布式计算环境。虽然MapReduce框架本身具有很好的可扩展性和容错性,但在某些情况下,任务执行可能会因为各种原因导致性能瓶颈。本文将探讨如何通过调整配置参数和优化算法逻辑来提高MapReduce任务的效率。
776 0

相关实验场景

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等