一个MapReduce 程序示例 细节决定成败(四) :In-Map Aggregation

为什么使用in-map aggregation, 与combine 有什么区别,什么时候使用combiner ,什么时候使用in-map 聚合?

先介绍用一张图看看一下combiner 在一个mr job中的位置。 



下面上干货:
数据文件 由  InputFormat 读取,传入到Map阶段处理。 Map处理完后,会把结果key value 对写到Map 任务节点内存中的一个环形缓存区。写到缓存区的Key Value 对已经是 序列化过的了,这是一个重点!
然后当map 任务结束或者缓存区使用率到一定阶段,会发生spill 溢写(map 端至少会发生一次磁盘写入),在spill溢写之前 会调用Combine 进行聚合。
那Combine 拿到已经序列化的key value 对后首先要进行反序列化,然后再进行聚合,然后再进行序列化写入磁盘。这是Combine的处理过程。
那in-map 聚合是什么概念? 
in-map 聚合是指,map结果输出时进行聚合,这样避免了反序列化-处理-再序列化 这样一个过程。
具体实现是使用到了Map 的一setup()  与 cleanup() 两个方法。
setup : 是当这map task 运行前首先执行的一个方法。
cleanup:是指当前map task运行结束时最后执行的一个方法。 

具体通过代码体会吧 :注意一点context.write 是在 cleanup方法中执行的。


点击(此处)折叠或打开

  1. public static class MyWordCountMapper extends
  2.                         Mapper<LongWritable, Text, Text, IntWritable> {
  3.                 Logger log = Logger.getLogger(MyWordCountJob.class);
  4.                 Map<Character,Integer> map = new HashMap<Character,Integer>();

  5.                 Text mapKey = new Text();
  6.                 IntWritable mapValue = new IntWritable(1);
  7.                 @Override
  8.                 protected void map(LongWritable key, Text value, Context context)
  9.                                 throws IOException, InterruptedException {
  10.                         for(char c :value.toString().toLowerCase().toCharArray()){
  11.                                 if(c>='a' && c <='z'){
  12.                                         map.put(c,map.get(c)+1);
  13.                                 }
  14.                         }
  15.                 }

  16.                 @Override
  17.                 protected void cleanup(Context context) throws IOException,
  18.                                 InterruptedException {
  19.                         for(char key : map.keySet()){
  20.                                 mapKey.set(String.valueOf(key));
  21.                                 mapValue.set(map.get(key));
  22.                                 context.write(mapKey, mapValue);
  23.                         }

  24.                 }

  25.                 @Override
  26.                 protected void setup(Context context) throws IOException,
  27.                                 InterruptedException {
  28.                         for(char c='a';c<='z' ;c++){
  29.                                 map.put(c, 0);
  30.                         }
  31.                 }

  32.         }

执行看结果


点击(此处)折叠或打开

  1. 16/05/11 06:25:30 INFO mapreduce.Job: Counters: 43
  2.         File System Counters
  3.                 FILE: Number of bytes read=630
  4.                 FILE: Number of bytes written=338285
  5.                 FILE: Number of read operations=0
  6.                 FILE: Number of large read operations=0
  7.                 FILE: Number of write operations=0
  8.                 HDFS: Number of bytes read=556
  9.                 HDFS: Number of bytes written=107
  10.                 HDFS: Number of read operations=12
  11.                 HDFS: Number of large read operations=0
  12.                 HDFS: Number of write operations=2
  13.         Job Counters
  14.                 Launched map tasks=3
  15.                 Launched reduce tasks=1
  16.                 Data-local map tasks=3
  17.                 Total time spent by all maps in occupied slots (ms)=515880
  18.                 Total time spent by all reduces in occupied slots (ms)=68176
  19.         Map-Reduce Framework
  20.                 Map input records=8
  21.                 Map output records=78
  22.                 Map output bytes=468
  23.                 Map output materialized bytes=642
  24.                 Input split bytes=399
  25.                 Combine input records=0
  26.                 Combine output records=0
  27.                 Reduce input groups=26
  28.                 Reduce shuffle bytes=642
  29.                 Reduce input records=78
  30.                 Reduce output records=26
  31.                 Spilled Records=156
  32.                 Shuffled Maps =3
  33.                 Failed Shuffles=0
  34.                 Merged Map outputs=3
  35.                 GC time elapsed (ms)=164
  36.                 CPU time spent (ms)=3490
  37.                 Physical memory (bytes) snapshot=1089146880
  38.                 Virtual memory (bytes) snapshot=3962114048
  39.                 Total committed heap usage (bytes)=868352000
  40.         Shuffle Errors
  41.                 BAD_ID=0
  42.                 CONNECTION=0
  43.                 IO_ERROR=0
  44.                 WRONG_LENGTH=0
  45.                 WRONG_MAP=0
  46.                 WRONG_REDUCE=0
  47.         File Input Format Counters
  48.                 Bytes Read=157
  49.         File Output Format Counters
  50.                 Bytes Written=107
通过Counter 可以看出Reducer 的输入为78个,  与使用Combiner 的效果是一样的。 而Map输出的记录数减少到了78个。

继续研究这个例子,可以看到 代码中定义了一个map,来存放所有的字符的数量。这个map中最大的记录数也就26个,占用内存不大,那这是适用的。
假如我们统计的是单词数量,而且单词数量很多,就可能会导致map task的内存中存放不下,那这种情况就是不适用的! 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30066956/viewspace-2107982/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30066956/viewspace-2107982/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值