MapReduce编程实例单词计数.docx
- 文档编号:10877310
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:9
- 大小:19.11KB
MapReduce编程实例单词计数.docx
《MapReduce编程实例单词计数.docx》由会员分享,可在线阅读,更多相关《MapReduce编程实例单词计数.docx(9页珍藏版)》请在冰豆网上搜索。
MapReduce编程实例单词计数
MapReduce编程实例:
单词计数
本节介绍如何编写基本的MapReduce程序实现数据分析。
本节代码是基于Hadoop2.7.3开发的。
任务准备
单词计数(WordCount)的任务是对一组输入文档中的单词进行分别计数。
假设文件的量比较大,每个文档又包含大量的单词,则无法使用传统的线性程序进行处理,而这类问题正是MapReduce可以发挥优势的地方。
在前面《MapReduce实例分析:
单词计数》教程中已经介绍了用MapReduce实现单词计数的基本思路和具体执行过程。
下面将介绍如何编写具体实现代码及如何运行程序。
首先,在本地创建3个文件:
file00l、file002和file003,文件具体内容如表1所示。
表1单词计数输入文件
文件名
file001
file002
file003
文件内容
Helloworld
Connectedworld
Oneworld
Onedream
HelloHadoop
HelloMap
HelloReduce
再使用HDFS命令创建一个input文件目录。
hadoopfs-mkdirinput
然后,把file001、file002和file003上传到HDFS中的input目录下。
hadoopfs-putfile001input
hadoopfs-putfile002input
hadoopfs-putfile003input
编写MapReduce程序的第一个任务就是编写Map程序。
在单词计数任务中,Map需要完成的任务就是把输入的文本数据按单词进行拆分,然后以特定的键值对的形式进行输出。
编写Map程序
HadoopMapReduce框架已经在类Mapper中实现了Map任务的基本功能。
为了实现Map任务,开发者只需要继承类Mapper,并实现该类的Map函数。
为实现单词计数的Map任务,首先为类Mapper设定好输入类型和输出类型。
这里,Map函数的输入是
所以,Map函数的输入类型为
Map函数的功能为完成文本分割工作,Map函数的输出也是
所以,Map函数的输出类型为
以下是单词计数程序的Map任务的实现代码。
1.publicstaticclassCoreMapperextendsMapper
2.privatestaticfinalIntWritableone=newIntWritable
(1);
3.privatestaticTextlabel=newText();
4.publicvoidmap(Objectkey,Textvalue,Mapper
5.StringTokenizertokenizer=newStringTokenizer(value.toString());
6.while(tokenizer.hasMoreTokens()){
7.label.set(tokenizer.nextToken());
8.context.write(label,one);
9.}
10.}
11.}
在上述代码中,实现Map任务的类为CoreMapper。
该类首先将需要输出的两个变量one和label进行初始化。
∙变量one的初始值直接设置为1,表示某个单词在文本中出现过。
∙Map函数的前两个参数是函数的输入参数,value为Text类型,是指每次读入文本的一行,key为Object类型,是指输入的行数据在文本中的行号。
StringTokenizer类机器方法将value变量中文本的一行文字进行拆分,拆分后的单词放在tokenizer列表中。
然后程序通过循环对每一个单词进行处理,把单词放在label中,把one作为单词计数。
在函数的整个执行过程中,one的值一直是1。
在该实例中,key没有被明显地使用到。
context是Map函数的一种输出方式,通过使用该变量,可以直接将中间结果存储在其中。
根据上述代码,Map任务结束后,3个文件的输出结果如表2所示。
表2单词计数Map任务输出结果
文件名/Map
file001/Map1
file002/Map2
file003/Map3
Map任务输出结果
<"Hello",1>
<"world",1>
<"Connected",1>
<"world",1>
<"One",1>
<"world",1>
<"One",1>
<"dream",1>
<"Hello",1>
<"Hadoop",1>
<"Hello",1>
<"Map",1>
<"Hello",1>
<"Reduce",1>
编写Reduce程序
编写MapReduce程序的第二个任务就是编写Reduce程序。
在单词计数任务中,Reduce需要完成的任务就是把输入结果中的数字序列进行求和,从而得到每个单词的出现次数。
在执行完Map函数之后,会进入Shuffle阶段,在这个阶段中,MapReduce框架会自动将Map阶段的输出结果进行排序和分区,然后再分发给相应的Reduce任务去处理。
经过Map端Shuffle阶段后的结果如表3所示。
表3单词计数Map端Shuffle阶段输出结果
文件名/Map
file001/Map1
file002/Map2
file003/Map3
Map端
Shuffle阶段输出结果
<"Connected",1>
<"Hello",1>
<"world",<1,1>>
<"dream",1>
<"One",<1,1>>
<"world",1>
<"Map",1>
<"Hadoop",1>
<"Hello",<1,1,1>>
<"Reduce",1>
Reduce端接收到各个Map端发来的数据后,会进行合并,即把同一个key,也就是同一单词的键值对进行合并,形成
经过Map端Shuffle阶段后的结果如表4所示。
表4单词计数Reduce端Shuffle阶段输出结果
Reduce端
<"Connected",1>
Shuffle阶段输出结果
<"dream",1>
<"Hadoop",1>
<"Hello",<1,1,1,1>>
<"Map",1>
<"One",<1,1>>
<"world",<1,1,1>>
<"Reduce",1>
Reduce阶段需要对上述数据进行处理从而得到每个单词的出现次数。
从Reduce函数的输入已经可以理解Reduce函数需要完成的工作,就是首先对输入数据value中的数字序列进行求和。
以下是单词计数程序的Reduce任务的实现代码。
1.publicstaticclassCoreReducerextendsReducer
2.
3.privateIntWritablecount=newIntWritable();
4.publicvoidreduce(Textkey,Iterable
5.intsum=0;
6.for(IntWritableintWritable:
values){
7.sum+=intWritable.get();
8.}
9.count.set(sum);
10.context.write(key,count);
11.}
12.}
与Map任务实现相似,Reduce任务也是继承Hadoop提供的类Reducer并实现其接口。
Reduce函数的输入、输出类型与Map函数的输出类型本质上是相同的。
在Reduce函数的开始部分,首先设置sum参数用来记录每个单词的出现次数,然后遍历value列表,并对其中的数字进行累加,最终就可以得到每个单词总的出现次数。
在输出的时候,仍然使用context类型的变量存储信息。
当Reduce阶段结束时,就可以得到最终需要的结果,如表5所示。
表5单词计数Reduce任务输出结果
Reduce任务输出结果
<"Connected",1>
<"dream",1>
<"Hadoop",1>
<"Hello",4>
<"Map",1>
<"One",2>
<"world",3>
<"Reduce",1>
编写main函数
为了使用CoreMapper和CoreReducer类进行真正的数据处理,还需要在main函数中通过Job类设置HadoopMapReduce程序运行时的环境变量,以下是具体代码。
1.publicstaticvoidmain(String[]args)throwsException{
2.Configurationconf=newConfiguration();
3.String[]otherArgs=newGenericOptionsParser(conf,args).getRemainingArgs();
4.if(otherArgs.length!
=2){
5.System.err.printIn("Usage:
wordcount
6.System.exit
(2);
7.}
8.Jobjob=newJob(conf,"WordCount");//设置环境参数
9.job.setJarByClass(WordCount.class);//设置程序的类名
10.job.setMapperClass(CoreMapper.class);//添加Mapper类
11.job.setReducerClass(CoreReducer.class);//添加Reducer类
12.job.setOutputKeyClass(Text.class);//设置输出key的类型
13.job.setOutputValueClass(IntWritable.class);
14.//设置输出value的类型
15.FileInputFormat.addInputPath(job,newPath(otherArgs[0]));
16.//设置输入文件路径
17.FileOutputFormat.setOutputPath(job,newPath(otherArgs[1]));
18.//设置输入文件路径
19.System.exit(job.waitForCompletion(true)?
0:
1);
20.}
代码首先检查参数是不是正确,如果不正确就提醒用户。
随后,通过Job类设置环境参数,并设置程序的类、Mapper类和Reducer类。
然后,设置了程序的输出类型,也就是Reduce函数的输出结果
最后,根据程序运行时的参数,设置输入、输出文件路径。
核心代码包
编写MapReduce程序需要引用Hadoop的以下几个核心组件包,它们实现了HadoopMapReduce框架。
1.importjava.io.IOException;
2.importjava.util.StringTokenizer;
3.importorg.apache.hadoop.conf.Configuration;
4.importorg.apache.hadoop.fs.Path;
5.importorg.apache.hadoop.io.IntWritable;
6.importorg.apache.hadoop.io.Text;
7.importorg.apache.hadoop.mapreduce.Job;
8.importorg.apache.hadoop.mapreduce.Mapper;
9.importorg.apache.hadoop.mapreduce.Reducer;
10.
11.importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;
12.importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
13.importorg.apache.hadoop.util.GenericOptionsParser;
这些核心组件包的基本功能描述如表6所示。
表6HadoopMapReduce核心组件包的基本功能
包
功能
org.apache.hadoop.conf
定义了系统参数的配置文件处理方法
org.apache.hadoop.fs
定义了抽象的文件系统API
org.apache.hadoop.mapreduce
HadoopMapReduce框架的实现,包括任务的分发调度等
org.apache.hadoop.io
定义了通用的I/OAPI,用于网络、数据库和文件数据对象进行读写操作
运行代码
在运行代码前,需要先把当前工作目录设置为/user/local/Hadoop。
编译WordCount程序需要以下3个Jar,为了简便起见,把这3个Jar添加到CLASSPATH中。
$export
CLASSPATH=/usr/local/hadoop/share/hadoop/common/hadoop-common-2.7.3.jar:
$CLASSPATH
$export
CLASSPATH=/usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-2.7.3.jar:
$CLASSPATH
$export
CLASSPATH=/usr/local/hadoop/share/hadoop/common/lib/common-cli-1.2.jar:
$CLASSPATH
使用JDK包中的工具对代码进行编译。
$javacWordCount.java
编译之后,在文件目录下可以发现有3个“.class”文件,这是 Java 的可执行文件,将它们打包并命名为wordcount.jar。
$jar-cvfwordcount.jar*.class
这样就得到了单词计数程序的Jar包。
在运行程序之前,需要启动Hadoop系统,包括启动HDFS和MapReduce。
然后,就可以运行程序了。
$./bin/Hadoopjarwordcount.jarWordCountinputoutput
最后,可以运行下面的命令查看结果。
$./bin/Hadoopfs-catoutput/*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MapReduce 编程 实例 单词 计数