要统计的文件的文件名为hello

hello中的内容如下

hello  you

hello  me

通过MapReduce程序统计出文件中的各个单词出现了几次.(两个单词之间通过tab键进行的分割)

 import java.io.IOException;

 import mapreduce.WordCountApp.WordCountMapper.WordCountReducer;

 import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* 以文本
* hello you
* hello me
* 为例子.
* map方法调用了两次,因为有两行
* k2 v2 键值对的数量有几个?
* 有4个.有四个单词.
*
* 会产生几个分组?
* 产生3个分组.
* 有3个不同的单词.
*
*/
public class WordCountApp {
public static void main(String[] args) throws Exception {
//程序在这里运行,要有驱动.
Configuration conf = new Configuration();
Job job = Job.getInstance(conf,WordCountApp.class.getSimpleName()); //我们运行此程序通过运行jar包来执行.一定要有这句话.
job.setJarByClass(WordCountApp.class); FileInputFormat.setInputPaths(job,args[0]); job.setMapperClass(WordCountMapper.class);//设置Map类
job.setMapOutputKeyClass(Text.class);//设置Map的key
job.setMapOutputValueClass(LongWritable.class);//设置Map的value
job.setReducerClass(WordCountReducer.class);//设置Reduce的类
job.setOutputKeyClass(Text.class);//设置Reduce的key Reduce这个地方只有输出的参数可以设置. 方法名字也没有Reduce关键字区别于Map
job.setOutputValueClass(LongWritable.class);//设置Reduce的value. FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);//表示结束了才退出,不结束不退出
}
/**
* 4个泛型的意识
* 第一个是LongWritable,固定就是这个类型,表示每一行单词的起始位置(单位是字节)
* 第二个是Text,表示每一行的文本内容.
* 第三个是Text,表示单词
* 第四个是LongWritable,表示单词的出现次数
*/
public static class WordCountMapper extends Mapper<LongWritable, Text, Text ,LongWritable>{
Text k2 = new Text();
LongWritable v2 = new LongWritable();
//增加一个计数器,这个Map调用几次就输出对应的次数.
int counter = 0; /**
* key和value表示输入的信息
* 每一行文本调用一次map函数
*/
@Override
protected void map(LongWritable key, Text value,Mapper<LongWritable, Text, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
counter = counter + 1;
System.out.println("mapper 调用的次数:" + counter);
//这个map方法中的Mapper的各个泛型和上面的意识是一样的,分别代表的是k1,v1,k2,v2
String line = value.toString();
System.out.println(String.format("<k1,v1>的值<"+key.get()+","+line+">"));
String[] splited = line.split("\t");
for (String word : splited) {
k2.set(word);
v2.set(1);
System.out.println(String.format("<k2,v2>的值<"+k2.toString()+","+v2.get()+">"));
context.write(k2, v2);//通过context对象写出去.
}
}
/**
* 这个地方的四个泛型的意思
* 前两个泛型是对应的Map方法的后两个泛型.
* Map的输出对应的是Reduce的输入.
* 第一个Text是单词
* 第二个LongWritable是单词对应的次数
* 我们想输出的也是单词 和 次数
* 所以第三个和第四个的类型和第一和第二个的一样
*
* 分组指的是把相同key2的value2放到一个集合中
*
*/
public static class WordCountReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
LongWritable v3 = new LongWritable();
//增加一个计数器,这个Reduce调用几次就输出对应的次数.
int counter = 0; /**
* 每一个分组调用一次reduce函数
* 过来的k2 分别是hello you me
*
*/
@Override
protected void reduce(Text key2, Iterable<LongWritable> value2Iterable,Reducer<Text, LongWritable, Text,
LongWritable>.Context context)
throws IOException, InterruptedException {
counter = counter + 1;
System.out.println("reducer 调用的次数:" + counter);
//第一个参数是单词,第二个是可迭代的集合. 为什么上面的LongWritable类型的对象value2变成了一个可以迭代的结合参数?
//因为分组指的是把相同key2的value2放到一个集合中
long sum = 0L;
for (LongWritable value2 : value2Iterable) {
System.out.println(String.format("<k2,v2>的值<"+key2.toString()+","+value2.toString()+">"));
sum += value2.get(); //这个value2是LongWritable类型的,不能进行+= 操作,要用get()得到其对应的java基本类型.
//sum表示单词k2 在整个文本中的出现次数.
}
v3.set(sum);
context.write(key2, v3);
System.out.println(String.format("<k3,v3>的值<"+key2.toString()+","+v3.get()+">"));
}
}
}
}

通过运行Yarn集群查看Map日志得到的输出结果:

查看Reduce日志产看到的输出结果:

//============================================================================

以下程序是之前的写的:注释更加详细:

 /*
* 一个hello文件内容如下:
* hello you
* hello me
*/
import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class WordCountApp {
public static void main(String[] args) throws Exception {
// 在main方法写驱动程序,把Map函数和Reduce函数组织在一起.
// 搞一个对象把Map对象和Reduce对象都放在这个对象中,我们把这个对象称作Job
// 两个形参,一个是Configuration对象,一个是Job的名称,这样获得了一个Job对象;
Job job = Job.getInstance(new Configuration(),
WordCountApp.class.getSimpleName());
// 对这个job进行设置
job.setJarByClass(WordCountApp.class);// 通过这个设置可以让框架识别你写的代码 job.setMapperClass(MyMapper.class);// 把自定义的Map类放到job中
job.setMapOutputKeyClass(Text.class);// 定义Map的key的输出类型,Map的输出是<hello,2>
job.setMapOutputValueClass(LongWritable.class);// 定义Map的value的输出类型 job.setReducerClass(MyReducer.class);// 把自定义的Reducer类放到job中
job.setOutputKeyClass(Text.class);// 因为Reduce的输出是最终的数据,Reduce的输出是<hello,2>
// 所以这个方法名中没有像Map对应的放发一样带有Reduce,直接就是setOutputKeyClass
job.setOutputValueClass(LongWritable.class);// 定义reduce的value输出 FileInputFormat.setInputPaths(job, args[0]);// 输入指定:传入一个job地址.
// 这个args[0] 就是新地址,"hdfs://192.168.0.170/hello"
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 输出指定
// 指定输入和输出路径可以通过在这里写死的方式,也可以通过main函数参数的形式
// 分别是args[0]和args[1] // 把job上传到yarn平台上.
job.waitForCompletion(true);
} /*
* 对于<k1,v1>而言,每一行产生一个<k1,v1>对,<k1,v1>表示<行的起始位置,行的文本内容>
* 就本例而言map函数总共调用两次,因为总共只有两行.
* 正对要统计的文本内容可以知道总共两行,总共会调用两次Map函数对应产生的<k1,v1>分别是<0,hello you>
* 和第二个<k1,v1>是<10,hello me>
*/
private static class MyMapper extends
Mapper<LongWritable, Text, Text, LongWritable> {
// 这个Mapper的泛型参数是<KEYIN,VALUEIN,KEYOUT,VALUEOUT> 分别对应的是k1,v1,k2,v2
// 我们如下讲的k1,v1的类型是固定的.
// 就本例而言,map函数会被调用2次,因为总共文本文件就只有两行. //要定义输出的k2和v2.本案例中可以分析出<k2,v2>是对文本内容的统计<hello,1><hello,1><you,1><me,1>
//而且<k2,v2>的内容是和<k3,v3>中的内容是一样的.
Text k2 = new Text();
LongWritable v2 = new LongWritable();
//重写父类Mapper中的map方法
@Override
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
//通过代码或者案例分析就可以知道k1其实没有什么用出的.
String line = value.toString();
String[] splited = line.split("\t");//根据制表分隔符机进行拆分.hello和me,you之间是一个制表分隔符.
for (String word : splited) {
k2.set(word);
v2.set(1);
context.write(k2, v2);
//用context把k2,v2写出去,框架会写,不用我们去管.
}
}
} private static class MyReducer extends
Reducer<Text, LongWritable, Text, LongWritable> {
//这个例子中的<k2,v2>和<k3,v3>中的k是一样的,所以这里,k2当做k3了.
LongWritable v3 = new LongWritable();
@Override
protected void reduce(Text k2, Iterable<LongWritable> v2s,
Reducer<Text, LongWritable, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
//Reduce是对上面Map中的结果进行汇总的.
//上面拆分出来的<k2,v2>是<hello,1><hello,1><you,1><me,1>Reduce方法中就要对其进行汇总.
long sum = 0L;
for(LongWritable v2:v2s){
sum = sum +v2.get();//sum是long类型,v2是LongWritable类型
//LongWritable类型转换成long类型用get()方法.
//sum的值表示单词在整个文件中出现的中次数.
}
v3.set(sum);
context.write(k2,v3);
}
} }

//===============================================================================

查看日志的时候,代码中的System.out.println()对于Java程序输出到控制台,但是这个地方是把Java类打成Jar包,

放到集群中去通过命令执行的.

输出通过日志查看的.

上面对应的Log Type:stdout

stdout:stdout(Standardoutput)标准输出

另外一个关于单词计数的总结:http://www.cnblogs.com/DreamDrive/p/5494866.html

关于MapReduce单词统计的例子:的更多相关文章

  1. MapReduce 单词统计案例编程

    MapReduce 单词统计案例编程 一.在Linux环境安装Eclipse软件 1.   解压tar包 下载安装包eclipse-jee-kepler-SR1-linux-gtk-x86_64.ta ...

  2. 2、 Spark Streaming方式从socket中获取数据进行简单单词统计

    Spark 1.5.2 Spark Streaming 学习笔记和编程练习 Overview 概述 Spark Streaming is an extension of the core Spark ...

  3. 大数据学习——mapreduce程序单词统计

    项目结构 pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...

  4. Hadoop分布环境搭建步骤,及自带MapReduce单词计数程序实现

    Hadoop分布环境搭建步骤: 1.软硬件环境 CentOS 7.2 64 位 JDK- 1.8 Hadoo p- 2.7.4 2.安装SSH sudo yum install openssh-cli ...

  5. Spark入门(三)--Spark经典的单词统计

    spark经典之单词统计 准备数据 既然要统计单词我们就需要一个包含一定数量的文本,我们这里选择了英文原著<GoneWithTheWind>(<飘>)的文本来做一个数据统计,看 ...

  6. 【Cloud Computing】Hadoop环境安装、基本命令及MapReduce字数统计程序

    [Cloud Computing]Hadoop环境安装.基本命令及MapReduce字数统计程序 1.虚拟机准备 1.1 模板机器配置 1.1.1 主机配置 IP地址:在学校校园网Wifi下连接下 V ...

  7. Java实现单词统计

    原文链接: https://www.toutiao.com/i6764296608705151496/ 单词统计的是统计一个文件中单词出现的次数,比如下面的数据源 其中,最终出现的次数结果应该是下面的 ...

  8. ytu 2002:C语言实验——单词统计(水题)

    C语言实验——单词统计 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 61  Solved: 34[Submit][Status][Web Board] ...

  9. 自定义实现InputFormat、OutputFormat、输出到多个文件目录中去、hadoop1.x api写单词计数的例子、运行时接收命令行参数,代码例子

    一:自定义实现InputFormat *数据源来自于内存 *1.InputFormat是用于处理各种数据源的,下面是实现InputFormat,数据源是来自于内存. *1.1 在程序的job.setI ...

随机推荐

  1. Delphi开发ocx插件的调试

    Delphi开发ocx苦于调试,网上看了下大概配置: IE调用ocx调试配置,在当前ocx工程  run-->parameters-->host application 里面配置IE的程序 ...

  2. homework-06

    围棋问题 关于代码的阅读,写注释,我的代码阅读量和阅读能力都有限,而且是关于没有基础的围棋问题,JAVA和C#混合的程序.不免参考了其他同学的思路,忘老师见谅. 1.playPrev(GoMove) ...

  3. JSF 2 textbox example

    In JSF, you can use the <h:inputText /> tag to render a HTML input of type="text", t ...

  4. mybatis杂记

    mybatis学习官网: 1.如果项目中使用maven管理,又引用 了mybatis框架, 下面是mybatis官网给出的 mybatis在maven中央仓库的坐标原文 详情见连接:https://c ...

  5. Windows xp下IDT Hook和GDT的学习

    一.前言   对于IDT第一次的认知是int 2e ,在系统调用的时候原来R3进入R0的方式就是通过int 2e自陷进入内核,然后进入KiSystemService函数,在根据系统服务调用号调用系统服 ...

  6. Python中的基本语句

    本文简单的介绍下Python的几个基本语句. print语句 print可同时打印多个表达式,只要将他们用逗号隔开. >>> name='Gumy' >>> gre ...

  7. Enterprise Library 4 数据访问应用程序块

    Enterprise Library 数据访问应用程序块简化了实现常规数据访问功能的开发任务.应用程序可以在各种场景中使用此应用程序块,例如为显示而读取数据.传递数据穿过应用程序层( applicat ...

  8. asp.net中使用swfupload上传大文件

    转载:http://www.cnblogs.com/niunan/archive/2012/01/12/2320705.html 花了一天多时间研究出来的,其实也就是网上下别人的代码然后再自己修修改改 ...

  9. 内容输出Linux文件系统的的实现:创建一个文件的过程

    题记:写这篇博客要主是加深自己对内容输出的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 考虑上面这个命令: who > userlist 当这个命令完成后,文件系统增加l一 ...

  10. BW性能优化

    少写例程,减少ABAP处理时间,例程要有效率减少查询数据库表先加载主数据,然后加载事务数据创建聚集进行数据压缩M:N关系的数据不能放到一个维度减少计算指标数量,提高上载效率并行加载建模型时如果有日的分 ...