mapreduce分组统计_Mapreduce程序WordCount单词计数详解

本文详细介绍了MapReduce实现WordCount的步骤,包括自定义Mapper、Combiner和Reducer。Mapper负责将输入文本拆分成单词,输出键值对;Combiner用于本地预聚合,减少网络传输;Reducer执行最终的聚合操作,统计每个单词出现的总次数。通过设置分组,优化MapReduce作业性能。
摘要由CSDN通过智能技术生成

importjava.io.IOException;

importjava.net.URI;

importjava.net.URISyntaxException;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.LongWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Mapper;

importorg.apache.hadoop.mapreduce.Job;

importorg.apache.hadoop.mapreduce.Reducer;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

publicclassWordCount {

staticfinalStringINPUT_PATH="hdfs://192.168.56.171:9000/WordCount/word";

staticfinalStringOUT_PATH="hdfs://192.168.56.171:9000/WordCount/out";

publicstaticvoidmain(String[]args)throwsIOException,

InterruptedException,

ClassNotFoundException, URISyntaxException {

Configurationconf=newConfiguration();

finalFileSystemfileSystem= FileSystem.get(newURI(INPUT_PATH),conf);

finalPathoutPath=newPath(OUT_PATH);

if(fileSystem.exists(outPath)) {

fileSystem.delete(outPath,true);

}

finalJobjob=newJob(conf, WordCount.class.getSimpleName());

//打包运行时必须执行的秘密方法

job.setJarByClass(WordCount.class);

// 1指定读取的文件位于哪里

FileInputFormat.setInputPaths(job,INPUT_PATH);

//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对

// job.setInputFormatClass(TextInputFormat.class);

// 2指定自定义的map类

job.setMapperClass(MyMapper.class);

// map输出的类型。如果的类型与类型一致,则可以省略

// job.setMapOutputKeyClass(Text.class);

// job.setMapOutputValueClass(LongWritable.class);

// 3分区

// job.setPartitionerClass(MyPartitioner.class);

//有一个reduce任务运行

job.setNumReduceTasks(1);

// 4TODO排序、分组+

// 5TODO规约

job.setCombinerClass(MyCombiner.class);

// 6指定自定义reduce类

job.setReducerClass(MyReducer.class);

//指定reduce的输出类型

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(LongWritable.class);

// 7指定写出到哪里

FileOutputFormat.setOutputPath(job,outPath);

//指定输出文件的格式化类

// job.setOutputFormatClass(TextOutputFormat.class);

//把job提交给JobTracker运行

job.waitForCompletion(true);

}

staticclassMyMapperextends

Mapper {

// LongWritable, Text和Text, LongWritable分别是输入与输出的数据类型

protectedvoidmap(LongWritablek1, Textv1, Contextcontext)

// k1指v1的偏移量,v1是指输入的文本数据,有下面的输出语句可得知,

// v1为一行的数据

throwsIOException,

InterruptedException {

System.out.println("k1="+k1+" ,v1="+v1);

//把v1转换成String类型,并以空格为分隔,存储在String字符数组中

finalStringline=v1.toString();

finalString[]splited=line.split(" ");

for(Stringword:splited) {

//使用context.write将此键值对输出,传递给reduce函数。

//而且此键值对类型与上面设定的输出的数据类型相同。

context.write(newText(word),newLongWritable(1L));

System.out.println("Mapper输出");

}

};

}

/*

* Combiner的使用,当map生成的数据过大时,可以精简压缩传给Reduce的数据,又不影响最重点数据,

* reduce的输入每个key值所对应的value都是1,这会占用很大的带宽。

* Combiner的使用可以使在map的输出在给于reduce之前做一下合并或计算,把具有相同key的value做一个计算,

*那么传给reduce的数据就会少很多,减轻了网络压力。

*通过代码可以看出Combiner是用reducer来定义的,因此多数的情况下Combiner和reduce处理的是同一种逻辑。

*只是reduce函数在内部完成的计算,通过Combiner的合并计算,使计算效率大大提高。

*/

staticclassMyCombinerextends

Reducer {

publicvoidreduce(Textk2,

Iterablev2, Contextcontext)

throwsIOException,

InterruptedException {

//显示次数表示reduce函数调用了多少次,表示课有多少个分组

System.out.println("Combiner输入分组");

longtimes= 0L;

for(LongWritablecount:v2) {

times+=count.get();

//显示次数表示k2,v2的键值对数量

System.out.println("Combiner输入键值对

+count.get()

+">");

}

context.write(k2,newLongWritable(times));

//显示次数表示k2,v2的键值对数量

System.out.println("Combiner最终输入键值对

+">");

}

}

staticclassMyReducerextends

// Text, LongWritable和Text, LongWritable分别是输入与输出的数据类型

//且Reducer函数的输入类型对应Mapper函数的输出类型。

Reducer {

//将相同的键的值放入到迭代器v2s中进行遍历。

protectedvoidreduce(Textk2,

Iterablev2s, Contextctx)

throwsIOException,

InterruptedException {

longtimes= 0L;

for(LongWritablecount:v2s) {

times+=count.get();

System.out.println("Reducer输入键值对

+count.get()

+">");

}

ctx.write(k2,newLongWritable(times));

};

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值