Hadoop之——Combiner编程

网友投稿 227 2022-11-20

Hadoop之——Combiner编程

一、Mapper类的实现

/** * KEYIN 即k1 表示行的偏移量 * VALUEIN 即v1 表示行文本内容 * KEYOUT 即k2 表示行中出现的单词 * VALUEOUT 即v2 表示行中出现的单词的次数,固定值1 */ static class MyMapper extends Mapper{ protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException { final String[] splited = v1.toString().split("\t"); for (String word : splited) { context.write(new Text(word), new LongWritable(1)); System.out.println("Mapper输出<"+word+","+1+">"); } }; }

二、Reducer类的实现

/** * KEYIN 即k2 表示行中出现的单词 * VALUEIN 即v2 表示行中出现的单词的次数 * KEYOUT 即k3 表示文本中出现的不同单词 * VALUEOUT 即v3 表示文本中出现的不同单词的总次数 * */ static class MyReducer extends Reducer{ protected void reduce(Text k2, java.lang.Iterable v2s, Context ctx) throws java.io.IOException ,InterruptedException { //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组 System.out.println("MyReducer输入分组<"+k2.toString()+",...>"); long times = 0L; for (LongWritable count : v2s) { times += count.get(); //显示次数表示输入的k2,v2的键值对数量 System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">"); } ctx.write(k2, new LongWritable(times)); }; }

三、Combiner的类实现

static class MyCombiner extends Reducer{ protected void reduce(Text k2, java.lang.Iterable v2s, Context ctx) throws java.io.IOException ,InterruptedException { //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组 System.out.println("Combiner输入分组<"+k2.toString()+",...>"); long times = 0L; for (LongWritable count : v2s) { times += count.get(); //显示次数表示输入的k2,v2的键值对数量 System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">"); } ctx.write(k2, new LongWritable(times)); //显示次数表示输出的k2,v2的键值对数量 System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">"); }; }

四、完整代码

package combine;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;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;/** * 问:为什么使用Combiner? * 答:Combiner发生在Map端,对数据进行规约处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。 * * 问:为什么Combiner不作为MR运行的标配,而是可选步骤哪? * 答:因为不是所有的算法都适合使用Combiner处理,例如求平均数。 * * 问:Combiner本身已经执行了reduce操作,为什么在Reducer阶段还要执行reduce操作哪? * 答:combiner操作发生在map端的,处理一个任务所接收的文件中的数据,不能跨map任务执行;只有reduce可以接收多个map任务处理的数据。 * */public class WordCountApp { static final String INPUT_PATH = "hdfs://liuyazhuang:9000/hello"; static final String OUT_PATH = "hdfs://liuyazhuang:9000/out"; public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf); final Path outPath = new Path(OUT_PATH); if(fileSystem.exists(outPath)){ fileSystem.delete(outPath, true); } final Job job = new Job(conf , WordCountApp.class.getSimpleName()); //1.1指定读取的文件位于哪里 FileInputFormat.setInputPaths(job, INPUT_PATH); //指定如何对输入文件进行格式化,把输入文件每一行解析成键值对 //job.setInputFormatClass(TextInputFormat.class); //1.2 指定自定义的map类 job.setMapperClass(MyMapper.class); //map输出的类型。如果的类型与类型一致,则可以省略 //job.setMapOutputKeyClass(Text.class); //job.setMapOutputValueClass(LongWritable.class); //1.3 分区 //job.setPartitionerClass(HashPartitioner.class); //有一个reduce任务运行 //job.setNumReduceTasks(1); //1.4 TODO 排序、分组 //1.5 规约 job.setCombinerClass(MyCombiner.class); //2.2 指定自定义reduce类 job.setReducerClass(MyReducer.class); //指定reduce的输出类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里 FileOutputFormat.setOutputPath(job, outPath); //指定输出文件的格式化类 //job.setOutputFormatClass(TextOutputFormat.class); //把job提交给JobTracker运行 job.waitForCompletion(true); } /** * KEYIN 即k1 表示行的偏移量 * VALUEIN 即v1 表示行文本内容 * KEYOUT 即k2 表示行中出现的单词 * VALUEOUT 即v2 表示行中出现的单词的次数,固定值1 */ static class MyMapper extends Mapper{ protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException { final String[] splited = v1.toString().split("\t"); for (String word : splited) { context.write(new Text(word), new LongWritable(1)); System.out.println("Mapper输出<"+word+","+1+">"); } }; } /** * KEYIN 即k2 表示行中出现的单词 * VALUEIN 即v2 表示行中出现的单词的次数 * KEYOUT 即k3 表示文本中出现的不同单词 * VALUEOUT 即v3 表示文本中出现的不同单词的总次数 * */ static class MyReducer extends Reducer{ protected void reduce(Text k2, java.lang.Iterable v2s, Context ctx) throws java.io.IOException ,InterruptedException { //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组 System.out.println("MyReducer输入分组<"+k2.toString()+",...>"); long times = 0L; for (LongWritable count : v2s) { times += count.get(); //显示次数表示输入的k2,v2的键值对数量 System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">"); } ctx.write(k2, new LongWritable(times)); }; } static class MyCombiner extends Reducer{ protected void reduce(Text k2, java.lang.Iterable v2s, Context ctx) throws java.io.IOException ,InterruptedException { //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组 System.out.println("Combiner输入分组<"+k2.toString()+",...>"); long times = 0L; for (LongWritable count : v2s) { times += count.get(); //显示次数表示输入的k2,v2的键值对数量 System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">"); } ctx.write(k2, new LongWritable(times)); //显示次数表示输出的k2,v2的键值对数量 System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">"); }; }}

五、运行结果

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java贪心算法初学感悟图解及示例分享
下一篇:Hadoop之——WorldCount统计实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~