热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java程序每步详解,通过Wordcount每步运行结果解析mapreduce是怎么运行的

Hadoop越来越火,而Hadoop里面有个核心的玩意,那就是MapReduce,它在Hadoop的并行计算中承担很重要的作用࿰

Hadoop越来越火,而Hadoop里面有个核心的玩意,那就是MapReduce,它在Hadoop的并行计算中承担很重要的作用,也是在Hadoop下做程序开发时,必须要了解的,下面我们就MapRecude的一个简单例子WordCount来做一下深入的了解和分析。

先跟远哥一起先了解一下什么是MapReduce吧。

首先MapReduce它是两个英文单词组成的,Map表示映射,Reduce表示化简,它是一种编程模型,用于大规模数据集(大于1TB)的并行运算,主要思想来自函数式编程。

在Hadoop中,MapReduce过程分三个步骤:Map(主要是分解并行的任务)、Combine(主要是为了提高Reduce的效率)和Reduce(把处理后的结果再汇总起来) 。

好了,我们先看一下运行一个Hadoop作业的启动代码:

Job job =

new Job(conf, "word count");

job.setJarByClass(WordCount.

class);

job.setMapperClass(

TokenizerMapper.

class);

job.setCombinerClass(

IntSumReducer.

class);

job.setReducerClass(

IntSumReducer.

class);

job.setOutputKeyClass(Text.

class);

job.setOutputValueClass(IntWritable.

class);

FileInputFormat.addInputPath(job,

new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job,

new Path(otherArgs[1]));

System.exit(job.waitForCompletion(

true) ? 0 : 1);

看到没,在运行一个Hadoop作业之前,先得指定 MapperClass 、CombinerClass 、ReducerClass .

假设我们交给Hadoop去分析的一个文本内容为:

lixy csy lixy zmde nitamade hehe

realy amoeba woyou weibo hehe

好了,提供的内容很简单,就是3行文本,第1行文本包含n个单词,第2行是空的,第3行也包含n个单词,单词与单词之间用空格隔开,下面我们来看看MapperClass 是如何实现的,又是如何运行的呢?看看 TokenizerMapper 的代码:

public

class TokenizerMapper

extends Mapper {

private

final

static IntWritable one =

new IntWritable(1);

private Text word =

new Text();

public

void map(Object key, Text value, Context context)

throws IOException, InterruptedException {

System.out.println(

"TokenizerMapper.map...");

System.out.println(

"Map key:"+key.toString()+

" Map value:"+value.toString());

StringTokenizer itr =

new StringTokenizer(value.toString());

while (itr.hasMoreTokens()) {

String tmp = itr.nextToken();

word.set(tmp);

context.write(word, one);

System.out.println(

"tmp:"+tmp+

" one:"+one);

}

System.out.println(

"context:"+context.toString());

}

}

注:这里远哥要说一下“IntWritable one = new IntWritable(1);”的用意,因为我们不管一个单词会出现几次,只要出现,我们就计算1次,所以“context.write(word, one)”这行代码将一个单词写入的时候,值永远是1;

在运行的时候,根据你文件中内容的情况,上面的 map(Object key, Text value, Context context) 方法可能会被调用多次,将本例子提供的文件内容执行后,控制台输出内容如下(为了方便阅读,我添加了一些换行):

TokenizerMapper.map...

Map key:0 Map value:lixy csy lixy zmde nitamade hehe

tmp:lixy one:1

tmp:csy one:1

tmp:lixy one:1

tmp:zmde one:1

tmp:nitamade one:1

tmp:hehe one:1

context:org.apache.hadoop.mapreduce.Mapper$Context@1af0b4a3

TokenizerMapper.map...

Map key:34 Map value:

context:org.apache.hadoop.mapreduce.Mapper$Context@1af0b4a3

TokenizerMapper.map...

Map key:36 Map value:realy amoeba woyou weibo hehe

tmp:realy one:1

tmp:amoeba one:1

tmp:woyou one:1

tmp:weibo one:1

tmp:hehe one:1

context:org.apache.hadoop.mapreduce.Mapper$Context@1af0b4a3

IntSumReducer.reduce...

val.get():1

Reduce key:amoeba Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:csy Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

val.get():1

Reduce key:hehe Reduce result:2

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:2

IntSumReducer.reduce...

val.get():1

val.get():1

Reduce key:lixy Reduce result:2

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:2

IntSumReducer.reduce...

val.get():1

Reduce key:nitamade Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:realy Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:weibo Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:woyou Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:zmde Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@d5d4de6 Result:1

从TokenizerMapper的 map(Object key, Text value, Context context) 调用的信息输出情况可以分析出,文件内容中有两行,所以该方法一共调用了2次(因为TextInputFormat类型的,都是按行处理)。

每一行的内容会在value参数中传进来,也就是说每一行的内容都对应了一个key,这个key为此行的开头位置在本文件中的所在位置(所以第1行的key是0,第2行的key是34,第3行的key是36),一般为数字的。

在这个map方法中,我们可以加入一些自己的处理逻辑,比如根据空格来取得每个单词,然后我们需要将处理后的结果,写入到context 参数中,便于hadoop处理完后续的处理逻辑。(这里我们需要注意的是“IntWritable one”变量都是数值1)

上面看了map的过程,接下来我们再看reduce的过程,先看看 IntSumReducer 的代码:

public class IntSumReducer extends    Reducer {

private IntWritable result = new IntWritable();

public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {

System.out.println("IntSumReducer.reduce...");

int sum = 0;

for (IntWritable val : values) {

sum += val.get();

System.out.println("val.get():" + val.get());

}

result.set(sum);

context.write(key, result);

System.out.println("Reduce key:" + key.toString() + " Reduce result:"    + result.get());

System.out.println("Reduce Context:" + context + " Result:" + result);

}

}

执行调用后,控制台输出内容如下:

IntSumReducer.reduce...

val.get():1

Reduce key:amoeba Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:csy Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():2

Reduce key:hehe Reduce result:2

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:2

IntSumReducer.reduce...

val.get():2

Reduce key:lixy Reduce result:2

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:2

IntSumReducer.reduce...

val.get():1

Reduce key:nitamade Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:realy Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:weibo Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:woyou Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

IntSumReducer.reduce...

val.get():1

Reduce key:zmde Reduce result:1

Reduce Context:org.apache.hadoop.mapreduce.Reducer$Context@6c04ab2f Result:1

通过执行reduce(Text key, Iterable values, Context context) 方法,奇迹发生了,hadoop传到这里的参数,已经去重了。什么意思呢?就是说,参数key里面是单词名称,如果一个单词出现2次,那么参数values里面就会2个值,但是key只有1次。像“lixy”这个单词在第一行出现了2次,那么这里的key只出现1次,但是后面的values会有2个IntWritable,并且值都是1,这个为1的值其实就是你在map的时候,自己定的。

这个例子只是简单的说明了MapReduce的一个简单使用,实际上他的功能远不只这些,还可以实现一些对数据库中数据的排序、统计等等,特别是对一些非常非常庞大的数据表。当你有一个1T的文本内容,需要统计里面每个单词分别出现多少次的时候,一台计算机去计算,会需要很长时间的,有可能光加载就要很长时间,但是如果你交给hadoop,并且配了几台机器一起跑的话,hadoop能把这1T的文本内容分成很多个小段,分发到不同的物理机器上,并行执行你的MapReduce逻辑,然后将几台物理机器上处理完成的内容汇总后给你,整个过程是分片、并行处理完成的,效率大大提高。



推荐阅读
  • MapReduce工作流程最详细解释
    MapReduce是我们再进行离线大数据处理的时候经常要使用的计算模型,MapReduce的计算过程被封装的很好,我们只用使用Map和Reduce函数,所以对其整体的计算过程不是太 ... [详细]
  • Maven构建Hadoop,
    Maven构建Hadoop工程阅读目录序Maven安装构建示例下载系列索引 序  上一篇,我们编写了第一个MapReduce,并且成功的运行了Job,Hadoop1.x是通过ant ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
  • MapReduce 切片机制源码分析
     总体来说大概有以下2个大的步骤1.连接集群(yarnrunner或者是localjobrunner)2.submitter.submitJobInternal()在该方法中会创建 ... [详细]
  • Hadoop之Yarn
    目录1Hadoop1.x和Hadoop2.x架构区别2Yarn概述3Yarn基本架构4Yarn工作机制5作业提交全过程6资源调度器7任务的推测执行1Hadoop1.x和Hadoo ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
author-avatar
曾wujcik_663
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有