分析MapReduce执行过程+统计单词数例子
MapReduce 运行的时候,会通过 Mapper 运行的任务读取 HDFS 中的数据文件,然后调用自己的方法,处理数据,最后输出。Reducer 任务会接收 Mapper 任务输出的数据,作为自己的输入数据,调用自己的方法,最后输出到 HDFS 的文件中。整个流程如图
Mapper任务的执行过程
- 第一阶段是把输入文件按照一定的标准分片(InputSplit),每个输入片的大小是固定的。默认情况下,输入片(InputSplit)的大小与数据块(Block)的大小是相同的。每一个输入片由一个 Mapper 进程处理。这里的三个输入片,会有三个 Mapper 进程处理。
- 第二阶段是对输入片中的记录按照一定的规则解析成键值对。 有个默认规则是把每一行文本内容解析成键值对。 “键”是每一行的起始位置(单位是字节), “值”是本行的文本内容。
- 第三阶段是调用 Mapper 类中的 map 方法。 第二阶段中解析出来的每一个键值对, 调用一次 map 方法。如果有 1000 个键值对,就会调用 1000 次 map 方法。每一次调用 map 方法会输出零个或者多个键值对。
- 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区。比较是基于键进行的。比如我们的键表示省份(如北京、上海、山东等),那么就可以按照不同省份进行分区,同一个省份的键值对划分到一个区中。默认是只有一个。分区的数量就是
Reducer 任务运行的数量。默认只有一个 Reducer 任务。- 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键相同的键值对,按照值进行排序。比如三个键值对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到本地的
linux 文件中。- 第六阶段是对数据进行归约处理,也就是 reduce 处理。键相等的键值对会调用一次reduce 方法。经过这一阶段,数据量会减少。归约后的数据输出到本地的 linxu 文件中。
Reducer任务的执行过程
- 第一阶段是 Reducer 任务会主动从 Mapper 任务复制其输出的键值对。 Mapper 任务可能会有很多,因此 Reducer 会复制多个 Mapper 的输出。
- 第二阶段是把复制到 Reducer 本地数据,全部进行合并,即把分散的数据合并成一个大的数据。再对合并后的数据排序。
- 第三阶段是对排序后的键值对调用 reduce 方法。 键相等的键值对调用一次 reduce 方法,每次调用会产生零个或者多个键值对。最后把这些输出的键值对写入到 HDFS 文件中。
在对 Mapper 任务、Reducer 任务的分析过程中,会看到很多阶段都出现了键值对,读者容易混淆,所以这里对键值对进行编号,方便大家理解键值对的变化情况。如图
对于 Mapper 任务输入的键值对,定义为 key1 和 value1。在 map 方法中处理后,输出的键值对,定义为 key2 和 value2。reduce 方法接收 key2 和 value2,处理后,输出 key3 和 value3。在下文讨论键值对时,可能把 key1 和 value1 简写为<k1,v1>,key2 和value2 简写为<k2,v2>,key3 和 value3 简写为<k3,v3>。
举例:单词计数
Mapper 任务输出的键值对按照键进行排序,键相等的键值对会调用一次 reduce 方法。在这里, “键”就是单词, “值”就是出现次数。因此可以在 reduce 方法中对单词的不同行中的所有出现次数相加,结果就是该单词的总的出现次数。最后把这个结果输出。
package mapreduce2;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
//key2 表示该行中的单词
final Text key2 = new Text();
//value2 表示单词在该行中的出现次数
final IntWritable value2 = new IntWritable(1);
//key 表示文本行的起始位置
//value 表示文本行
protected void map(LongWritable key, Text value, Context context) throws java.io.IOException, InterruptedException {
final String[] splited = value.toString().split(" ");
for (String word : splited) {
key2.set(word);
//把key2、value2写入到context中
context.write(key2, value2);
}
};
}
map 方法的第二个形参是行文本内容,是我们关心的。核心代码是把行文本内容按照空格拆分,把每个单词作为新的键,数值 1作为新的值,写入到上下文 context 中。在这里,因为输出的是每个单词,所以出现次数是常量 1。如果一行文本中包括两个 hello,会输出两次<hello,1>。
package mapreduce2;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
//value3表示单词出现的总次数
final IntWritable value3 = new IntWritable(0);
/**
* key 表示单词
* values 表示map方法输出的1的集合
* context 上下文对象
*/
protected void reduce(Text key, java.lang.Iterable<IntWritable> values, Context context) throws java.io.IOException, InterruptedException {
int sum = 0;
for (IntWritable count : values) {
sum += count.get();
}
//执行到这里,sum表示该单词出现的总次数
//key3表示单词,是最后输出的key
final Text key3 = key;
//value3表示单词出现的总次数,是最后输出的value
value3.set(sum);
context.write(key3, value3);
};
}
Reducer 类的四个泛型依次是<k2,v2,k3,v3>,要注意 reduce 方法的第二个参数是 java.lang.Iterable 类型,迭代的是 v2。也就是 k2 相同的 v2 都可以迭代出来。
package mapreduce2;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;
public class WordCountApp {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
//输入路径
final String INPUT_PATH = "hdfs://hadoop:9000/word.txt";
//输出路径,必须是不存在的
final String OUTPUT_PATH = "hdfs://hadoop:9000/output4";
//创建一个job对象,封装运行时需要的所有信息
final Job job = new Job(new Configuration(), "WordCountApp");
//如果需要打成jar运行,需要下面这句
//job.setJarByClass(WordCountApp.class);
//告诉job执行作业时输入文件的路径
FileInputFormat.setInputPaths(job, INPUT_PATH);
//设置把输入文件处理成键值对的类
job.setInputFormatClass(TextInputFormat.class);
//设置自定义的Mapper类
job.setMapperClass(MyMapper.class);
//设置map方法输出的k2、v2的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//设置对k2分区的类
job.setPartitionerClass(HashPartitioner.class);
//设置运行的Reducer任务的数量
job.setNumReduceTasks(1);
//设置自定义的Reducer类
job.setReducerClass(MyReducer.class);
//设置reduce方法输出的k3、v3的类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//告诉job执行作业时的输出路径
FileOutputFormat.setOutputPath(job, new Path(OUTPUT_PATH));
//指明输出的k3类型
job.setOutputKeyClass(Text.class);
//指明输出的v3类型
job.setOutputValueClass(IntWritable.class);
//让作业运行,直到运行结束,程序退出
job.waitForCompletion(true);
}
}
在以上代码中,我们创建了一个 job 对象,这个对象封装了我们的任务,可以提交到Hadoop 独立运行。最后一句 job.waitForCompletion(true),表示把 job 对象提交给 Hadoop 运行,直到作业运行结束后才可以。
分析MapReduce执行过程+统计单词数例子的更多相关文章
- 分析MapReduce执行过程
分析MapReduce执行过程 MapReduce运行的时候,会通过Mapper运行的任务读取HDFS中的数据文件,然后调用自己的方法,处理数据,最后输出. Reducer任务会接收Mapper任务输 ...
- Hadoop MapReduce执行过程详解(带hadoop例子)
https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...
- Hadoop MapReduce执行过程实例分析
1.MapReduce是如何执行任务的?2.Mapper任务是怎样的一个过程?3.Reduce是如何执行任务的?4.键值对是如何编号的?5.实例,如何计算没见最高气温? 分析MapReduce执行过程 ...
- Hadoop学习之Mapreduce执行过程详解
一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...
- 洛谷 P1308 统计单词数【字符串+模拟】
P1308 统计单词数 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定 ...
- 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(三)之 ResultSetHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(四)之延迟加载
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- MapReduce执行过程
Mapper任务的执行过程: 第一阶段是把输入文件按照一定的标准分片(InputSplit),每个输入片的大小是固定的.默认情况下,输入片(InputSplit)的大小与数据块(Block)的大小是相 ...
随机推荐
- java利用poi来读取execl表格返回对象
利用poi来读取execl表格,返回一个对象(可能有点不完善,但是应该能满足平常的所用),用到了反射等等; 使用的jar包有: commons-collections4-4.1.jar poi-3.1 ...
- scrapy爬取数据进行数据库存储和本地存储
今天记录下scrapy将数据存储到本地和数据库中,不是不会写,因为小编每次都写觉得都一样,所以记录下,以后直接用就可以了-^o^- 1.本地存储 设置pipel ines.py class Ak17P ...
- 词向量:part 1 WordNet、SoW、BoW、TF-IDF、Hash Trick、共现矩阵、SVD
1.基于知识的表征 如WordNet(图1-1),包含同义词集(synonym sets)和上位词(hypernyms,is a关系). 存在的问题: 作为资源来说是好的,但是它失去了词间的细微差别, ...
- [POI 2006]OKR-Periods of Words
Description 题库链接 定义 \(A\) 串为 \(B\) 串的循环串,当且仅当 \(A\) 是 \(B\) 的前缀(不包括 \(B\) 本身),且 \(B\) 为连续的 \(A\) 串拼接 ...
- hdu 5012(bfs)
题意:给你2个 骰子,让你通过翻转使第一个变成第二个,求最少翻转数 思路:bfs #include<cstdio> #include<iostream> #include< ...
- 文本分类学习 (五) 机器学习SVM的前奏-特征提取(卡方检验续集)
前言: 上一篇比较详细的介绍了卡方检验和卡方分布.这篇我们就实际操刀,找到一些训练集,正所谓纸上得来终觉浅,绝知此事要躬行.然而我在躬行的时候,发现了卡方检验对于文本分类来说应该把公式再变形一般,那样 ...
- C++ C# python 中常用数学计算函数对比
1.求x 的n次幂. C++ #include<cmath> f=pow(x,n) C# f=Math.Pow(x,n) python import numpy as np f=np.po ...
- SpringMVC 环境搭建(HelloWorld)
SpringMVC 入门案例 环境 * springMVC * web 构建文件目录结构 修改dispatcher-servlet.xml文件 修改web.xml
- EtherChannel(PAgP、LACP)基本配置--端口聚合--(转)
转自 http://blog.sina.com.cn/s/blog_635e1a9e01017msv.html EtherChannel EtherChannel(以太通道)也叫端口聚合或链路聚合,特 ...
- combobox数据绑定
jquery easyui datagrid 可编辑行 combobox数据绑定问题 将带有参数的url地址赋值给变量,然后将变量赋值给url <script type="text/j ...