In the last post we saw how to run a MapReduce job on Hadoop. Now we're going to analyze how a MapReduce program works. And, if you don't know what MapReduce is, the short answer is "MapReduce is a programming model for processing large data sets with a parallel, distributed algorithm on a cluster" (from Wikipedia).

Let's take a look at the source code: we can find a Java main method that is called from Hadoop, and two inner static classes, the mapper and the reducer. The code for the mapper is:

public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {

        private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); @Override
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}

As we can see, this class extends Mapper, which - as its JavaDoc says - maps input key/value pairs to a set of intermediate key/value pairs; when the job starts, the Hadoop framework passes to the mapper a chunk of data (a subset of the whole dataset) to process. The output of the mapper will be the input of the reducers (it's not the complete story, but we'll arrive there in another post). The Mapper uses Java generics to specify what kind of data will process; in this example, we use a class that extends Mapper and specifies Object and Text as the classes of key/value pairs in input, and Text and IntWritable as the classes of key/value pairs for the output to the reducers (we'll see the details of those classes in a moment). 
Let's examine the code: there's only one overridden method, the map() that takes the key/value pair as arguments and the Hadoop context; every time this method is called by Hadoop, the method receives an offset of the file where the value is as the key, and a line of the text file we're reading as the value. 
Hadoop has some basic types that ore optimized for network serialization; here is a table with a few of them:

Java type Hadoop type
Integer IntWritable
Long LongWritable
Double DoubleWritable
String TextWritable
Map MapWritable
Array ArrayWritable

Now it's easy to understand what this method does: for every line of the book it receives, it uses a StringTokenizer to split the line into every single word; then it sets the word in the Textobject and maps it the the value of 1; then writes it to the mappers via the Hadoop context.

Let's now look at the reducer:

public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable(); @Override
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}

This time we have the first two arguments of the overridden method reduce that are the same type of the last two of the TokenizerMapper class; that's because - as we said - the mapper outputs the data that the reducer will use as an input. The Hadoop framework takes care of calling this method for every key that comes from the mappers; as we saw before, the keys are the words of the file we're counting the words of. 
The reduce method now has to sum all the occurrences of every single word, so it initializes a sum variable to 0 and then loops over all the values for that specific key that it receives from the mappers. For every word it updates the sum variable with the value mapped to that key. At the end of the loop, when all the occurrences of that word are counted, the method sets the value obtained into an IntWritable object and gives it to the Hadoop context to be outputted to the user.

We're now at the main method of the class, which is the one that is called by Hadoop when it's executed as a JAR file.

public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
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);
}
}

In the method, we first setup a Configuration object, then we check for the number of arguments passed to it; If the number of arguments is correct, we create a Job object and we set a few values for making it work. Let's dive into the details:

  • setJarByClass: sets the Jar by finding where a given class came from; this needs an explanation: Hadoop distributes the code to execute to the cluster as a JAR file; instead of specifying the name of the JAR, we tell Hadoop the name of the class that every instance on the cluster has to look for inside its classpath
  • setMapperClass: sets the class that will be executed as the mapper
  • setCombinerClass: sets the class that will be executed as the combiner (we'll explain what is a combiner in a future post)
  • setReducerClass: sets the class that will be executed as the reducer
  • setOutputKeyClass: sets the class that will be used as the key for outputting data to the user
  • setOutputValueClass: sets the class that will be used as the value for outputting data to the user

Then we say to Hadoop where it can find the input with the FileInputFormat.addInputPath() method and where it has to write the output with the FileOutputFormat.setOutputPath()method. The last method call is the waitForCompletion(), that submits the job to the cluster and waits for it to finish.

Now that the mechanism of a MapReduce job is more clear, we can start playing with it.

from: http://andreaiacono.blogspot.com/2014/02/mapreduce-job-explained.html

MapReduce任务分析与讨论MapReduce job explained的更多相关文章

  1. MapReduce教程(一)基于MapReduce框架开发<转>

    1 MapReduce编程 1.1 MapReduce简介 MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算,用于解决海量数据的计算问题. MapReduce分成了两个部分: ...

  2. Migrating from MapReduce 1 (MRv1) to MapReduce 2 (MRv2, YARN)...

    This is a guide to migrating from Apache MapReduce 1 (MRv1) to the Next Generation MapReduce (MRv2 o ...

  3. 使用Cloudera Manager搭建MapReduce集群及MapReduce HA

    使用Cloudera Manager搭建MapReduce集群及MapReduce HA 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.通过CM部署MapReduce On ...

  4. 【MapReduce】一、MapReduce简介与实例

    (一)MapReduce介绍 1.MapReduce简介   MapReduce是Hadoop生态系统的一个重要组成部分,与分布式文件系统HDFS.分布式数据库HBase一起合称为传统Hadoop的三 ...

  5. hadoop2.2编程:从default mapreduce program 来理解mapreduce

    下面写一个default mapreduce 的程序: import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapr ...

  6. Top N之MapReduce程序加强版Enhanced MapReduce for Top N items

    In the last post we saw how to write a MapReduce program for finding the top-n items of a dataset. T ...

  7. Python实现MapReduce,wordcount实例,MapReduce实现两表的Join

    Python实现MapReduce 下面使用mapreduce模式实现了一个简单的统计日志中单词出现次数的程序: from functools import reduce from multiproc ...

  8. yarn/mapreduce工作机制及mapreduce客户端代码编写

    首先需要知道的就是在老版本的hadoop中是没有yarn的,mapreduce既负责资源分配又负责业务逻辑处理.为了解耦,把资源分配这块抽了出来,形成了yarn,这样不仅mapreudce可以用yar ...

  9. 【MapReduce】三、MapReduce运行机制

      通过前面对map端.reduce端以及整个shuffle端工作流程的介绍,我们已经了解了MapReduce的并行运算模型,基本可以使用MapReduce进行编程,那么MapRecude究竟是如何执 ...

随机推荐

  1. BZOJ 1861: [Zjoi2006]Book 书架 (splay)

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1453  Solved: 822[Submit][Stat ...

  2. java程序员修炼之道——大牛告诉我们应该好好学习与修炼以下知识与技能

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 一:Java语言学习(对线程(thread),串行化,反射,网络编程,JNI技术, ...

  3. Filter的应用--权限过滤

    因为项目比较长,需要一步步进行实现,所以分解成一个一个需求. 一:需求一 1.需求一 可以看某人的权限,同时,可以对这个用户进行权限的修改. 2.程序实现 3.程序目录 4.User.java pac ...

  4. Ionic Js五:单选框操作

    实例中,根据选中的不同选项,显示不同的值. HTML 代码 <ion-header-bar class="bar-positive"> <h1 class=&qu ...

  5. 使用GNU工具链进行嵌入式裸机开发

    Embedded-Programming-with-the-GNU-Toolchain Vijay Kumar B. vijaykumar@bravegnu.org 翻译整理:thammer gith ...

  6. Bipartite Graph hdu 5313 bitset 并查集 二分图

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313 题意: 给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图 存储结构: bitset   ...

  7. iOS 11开发教程(十二)iOS11应用视图始祖——UIView

    iOS 11开发教程(十二)iOS11应用视图始祖——UIView 在Swift中,NSObject是所有类的根类.同样在UIKit框架(UIKit框架为iOS应用程序提供界面对象和控制器)中,也存在 ...

  8. Django-高级特性

    分页 1.固定显示分页数目 2.点击相应分页取出对应数据 具体实现: from django.utils.safestring import mark_safe class Pagination(ob ...

  9. pip作用

    介绍 pip 是一个安装和管理 Python 包的工具,python安装包的工具有easy_install, setuptools, pip,distribute.使用这些工具都能下载并安装djang ...

  10. linux服务器安装swoole扩展

    说明: swoole只能用在LInux,macos系统上,不能用作Windows系统上 2.0.12版本开始不再支持PHP5 安装方式一:pecl安装 适用于php7.0以上版本 centOS中: # ...