Hadoop之——Combiner编程

转载请注明出处:http://blog.youkuaiyun.com/l1028386804/article/details/46135857
一、Mapper类的实现
  1. /** 
  2.  * KEYIN    即k1     表示行的偏移量 
  3.  * VALUEIN  即v1     表示行文本内容 
  4.  * KEYOUT   即k2     表示行中出现的单词 
  5.  * VALUEOUT 即v2     表示行中出现的单词的次数,固定值1 
  6.  */  
  7. static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{  
  8.     protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {  
  9.         final String[] splited = v1.toString().split("\t");  
  10.         for (String word : splited) {  
  11.             context.write(new Text(word), new LongWritable(1));  
  12.             System.out.println("Mapper输出<"+word+","+1+">");  
  13.         }  
  14.     };  
  15. }  
二、Reducer类的实现
  1. /** 
  2.  * KEYIN    即k2     表示行中出现的单词 
  3.  * VALUEIN  即v2     表示行中出现的单词的次数 
  4.  * KEYOUT   即k3     表示文本中出现的不同单词 
  5.  * VALUEOUT 即v3     表示文本中出现的不同单词的总次数 
  6.  * 
  7.  */  
  8. static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{  
  9.     protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {  
  10.         //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组  
  11.         System.out.println("MyReducer输入分组<"+k2.toString()+",...>");  
  12.         long times = 0L;  
  13.         for (LongWritable count : v2s) {  
  14.             times += count.get();  
  15.             //显示次数表示输入的k2,v2的键值对数量  
  16.             System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">");  
  17.         }  
  18.         ctx.write(k2, new LongWritable(times));  
  19.     };  
  20. }  
三、Combiner的类实现
  1. static class MyCombiner extends Reducer<Text, LongWritable, Text, LongWritable>{  
  2.     protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {  
  3.         //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组  
  4.         System.out.println("Combiner输入分组<"+k2.toString()+",...>");  
  5.         long times = 0L;  
  6.         for (LongWritable count : v2s) {  
  7.             times += count.get();  
  8.             //显示次数表示输入的k2,v2的键值对数量  
  9.             System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">");  
  10.         }  
  11.           
  12.         ctx.write(k2, new LongWritable(times));  
  13.         //显示次数表示输出的k2,v2的键值对数量  
  14.         System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">");  
  15.     };  
  16. }  
四、完整代码
  1. package combine;  
  2.   
  3. import java.net.URI;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.fs.FileSystem;  
  7. import org.apache.hadoop.fs.Path;  
  8. import org.apache.hadoop.io.LongWritable;  
  9. import org.apache.hadoop.io.Text;  
  10. import org.apache.hadoop.mapreduce.Job;  
  11. import org.apache.hadoop.mapreduce.Mapper;  
  12. import org.apache.hadoop.mapreduce.Reducer;  
  13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  15.   
  16. /** 
  17.  * 问:为什么使用Combiner? 
  18.  * 答:Combiner发生在Map端,对数据进行规约处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。 
  19.  *  
  20.  * 问:为什么Combiner不作为MR运行的标配,而是可选步骤哪? 
  21.  * 答:因为不是所有的算法都适合使用Combiner处理,例如求平均数。 
  22.  * 
  23.  * 问:Combiner本身已经执行了reduce操作,为什么在Reducer阶段还要执行reduce操作哪? 
  24.  * 答:combiner操作发生在map端的,处理一个任务所接收的文件中的数据,不能跨map任务执行;只有reduce可以接收多个map任务处理的数据。 
  25.  * 
  26.  */  
  27. public class WordCountApp {  
  28.     static final String INPUT_PATH = "hdfs://liuyazhuang:9000/hello";  
  29.     static final String OUT_PATH = "hdfs://liuyazhuang:9000/out";  
  30.       
  31.     public static void main(String[] args) throws Exception {  
  32.         Configuration conf = new Configuration();  
  33.         final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);  
  34.         final Path outPath = new Path(OUT_PATH);  
  35.         if(fileSystem.exists(outPath)){  
  36.             fileSystem.delete(outPath, true);  
  37.         }  
  38.           
  39.         final Job job = new Job(conf , WordCountApp.class.getSimpleName());  
  40.         //1.1指定读取的文件位于哪里  
  41.         FileInputFormat.setInputPaths(job, INPUT_PATH);  
  42.         //指定如何对输入文件进行格式化,把输入文件每一行解析成键值对  
  43.         //job.setInputFormatClass(TextInputFormat.class);  
  44.           
  45.         //1.2 指定自定义的map类  
  46.         job.setMapperClass(MyMapper.class);  
  47.         //map输出的<k,v>类型。如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略  
  48.         //job.setMapOutputKeyClass(Text.class);  
  49.         //job.setMapOutputValueClass(LongWritable.class);  
  50.           
  51.         //1.3 分区  
  52.         //job.setPartitionerClass(HashPartitioner.class);  
  53.         //有一个reduce任务运行  
  54.         //job.setNumReduceTasks(1);  
  55.           
  56.         //1.4 TODO 排序、分组  
  57.           
  58.         //1.5 规约  
  59.         job.setCombinerClass(MyCombiner.class);  
  60.           
  61.         //2.2 指定自定义reduce类  
  62.         job.setReducerClass(MyReducer.class);  
  63.         //指定reduce的输出类型  
  64.         job.setOutputKeyClass(Text.class);  
  65.         job.setOutputValueClass(LongWritable.class);  
  66.           
  67.         //2.3 指定写出到哪里  
  68.         FileOutputFormat.setOutputPath(job, outPath);  
  69.         //指定输出文件的格式化类  
  70.         //job.setOutputFormatClass(TextOutputFormat.class);  
  71.           
  72.         //把job提交给JobTracker运行  
  73.         job.waitForCompletion(true);  
  74.     }  
  75.       
  76.     /** 
  77.      * KEYIN    即k1     表示行的偏移量 
  78.      * VALUEIN  即v1     表示行文本内容 
  79.      * KEYOUT   即k2     表示行中出现的单词 
  80.      * VALUEOUT 即v2     表示行中出现的单词的次数,固定值1 
  81.      */  
  82.     static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{  
  83.         protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {  
  84.             final String[] splited = v1.toString().split("\t");  
  85.             for (String word : splited) {  
  86.                 context.write(new Text(word), new LongWritable(1));  
  87.                 System.out.println("Mapper输出<"+word+","+1+">");  
  88.             }  
  89.         };  
  90.     }  
  91.       
  92.     /** 
  93.      * KEYIN    即k2     表示行中出现的单词 
  94.      * VALUEIN  即v2     表示行中出现的单词的次数 
  95.      * KEYOUT   即k3     表示文本中出现的不同单词 
  96.      * VALUEOUT 即v3     表示文本中出现的不同单词的总次数 
  97.      * 
  98.      */  
  99.     static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{  
  100.         protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {  
  101.             //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组  
  102.             System.out.println("MyReducer输入分组<"+k2.toString()+",...>");  
  103.             long times = 0L;  
  104.             for (LongWritable count : v2s) {  
  105.                 times += count.get();  
  106.                 //显示次数表示输入的k2,v2的键值对数量  
  107.                 System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">");  
  108.             }  
  109.             ctx.write(k2, new LongWritable(times));  
  110.         };  
  111.     }  
  112.       
  113.       
  114.     static class MyCombiner extends Reducer<Text, LongWritable, Text, LongWritable>{  
  115.         protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {  
  116.             //显示次数表示redcue函数被调用了多少次,表示k2有多少个分组  
  117.             System.out.println("Combiner输入分组<"+k2.toString()+",...>");  
  118.             long times = 0L;  
  119.             for (LongWritable count : v2s) {  
  120.                 times += count.get();  
  121.                 //显示次数表示输入的k2,v2的键值对数量  
  122.                 System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">");  
  123.             }  
  124.               
  125.             ctx.write(k2, new LongWritable(times));  
  126.             //显示次数表示输出的k2,v2的键值对数量  
  127.             System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">");  
  128.         };  
  129.     }  
  130. }  
五、运行结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值