分享

Hadoop中调试(mapreduce)map与redcue信息的输出办法

 whbsdu 2015-01-08
Hadoop调试是比较麻烦的事情,考虑到只能通过reduce输出数据,我们可以把调试信息输出到reduce中,然后固定到某个文件中。

我们可以把所有的调试数据都是用key=“Debug”,调试信息作为value=“debugInfo”。
(1)在map中直接使用
output.collect(new Text("debug"), new Text("调试信息"));
(2)在reduce中判断

  1. if(key. equals ("debug"))
  2. {
  3.                             while (values.hasNext())
  4.                             {
  5.                                 String line = values.next().toString();
  6.                                 output.collect(new Text("debug"), new Text(line));
  7.                             }
  8. }
复制代码

(3)增加类ReportOutFormat
  1. public static class ReportOutFormat<K extends WritableComparable<?>, V extends Writable>
  2.     extends MultipleOutputFormat<K, V> {
  3. private TextOutputFormat<K, V> theTextOutputFormat = null;
  4. @Override
  5. protected RecordWriter<K, V> getBaseRecordWriter(FileSystem fs,
  6.         JobConf job, String name, Progressable arg3) throws IOException {
  7.     if (theTextOutputFormat == null) {
  8.         theTextOutputFormat = new TextOutputFormat<K, V>();
  9.     }
  10.     return theTextOutputFormat.getRecordWriter(fs, job, name, arg3);
  11. }
  12. @Override
  13. protected String generateFileNameForKeyValue(K key, V value, String name) {
  14.     if(key.equals("debug"))   ///注意这个判断
  15.         return "debug"+name;
  16.     return name ;
  17. }
  18. }
复制代码
(4)在configJob里面添加代码
  1. protected void configJob(JobConf conf)
  2. {
  3.           conf.setMapOutputKeyClass(Text.class);
  4.           conf.setMapOutputValueClass(Text.class);
  5.           conf.setOutputKeyClass(Text.class);  
  6.           conf.setOutputValueClass(Text.class);
  7.           conf.setOutputFormat(ReportOutFormat.class); //增加该行
  8. }
复制代码
这样在输出文件中我们就可以得到调试信息了。这个办法有点曲线救国的意思,不知道有没有其他方便的办法。




这里补充,还可以通过其他方法来进行调试:

可以通过 context.getCounter输出到控制台:
Counter countPrint1 = context.getCounter("Map中循环strScore", strScore);
                                countPrint1.increment(1l);


上面需要导入包:import org.apache.hadoop.mapreduce.Counter;




如下实例:将这两个类放到如项目中,或则为了验证效果,可以直接把下面内容放入项目中
Counter countPrint1 = context.getCounter("Map中循环strScore", “输出信息”);
countPrint1.increment(1l);



实例:


  1. // map类
  2.         static class MyMapper extends
  3.                         Mapper<LongWritable, Text, Text, LongWritable> {
  4.                 protected void map(LongWritable key, Text value, Context context)
  5.                                 throws IOException, InterruptedException {

  6.                

  7.                         String line = value.toString();
  8.                         Counter countPrint = context.getCounter("Map输出传递Value", line);
  9.                         countPrint.increment(1l);
  10.                         // 将输入的数据首先按行进行分割

  11.                         StringTokenizer tokenizerArticle = new StringTokenizer(line, "\n");

  12.                         // 分别对每一行进行处理

  13.                         while (tokenizerArticle.hasMoreElements()) {

  14.                                 // 每行按空格划分

  15.                                 StringTokenizer tokenizerLine = new StringTokenizer(
  16.                                                 tokenizerArticle.nextToken());

  17.                                 // String strName = tokenizerLine.nextToken();// 学生姓名部分

  18.                                 String strScore = tokenizerLine.nextToken();// 成绩部分
  19.                                 Counter countPrint1 = context.getCounter("Map中循环strScore", strScore);
  20.                                 countPrint1.increment(1l);
  21.                                 // Text name = new Text(strName);

  22.                                 int scoreInt = Integer.parseInt(strScore);

  23.                                 // 输出姓名和成绩

  24.                                 context.write(new Text("avg"), new LongWritable(scoreInt));

  25.                         }

  26.                 }

  27.         }
复制代码







  1. // reduce类
  2.         static class MyReduce extends
  3.                         Reducer<Text, LongWritable, Text, LongWritable> {
  4.                 @Override
  5.                 protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s,
  6.                                 Context ctx) throws java.io.IOException, InterruptedException {

  7.                
  8.                         long sum = 0;

  9.                         long count = 0;

  10.                         Iterator<LongWritable> iterator = v2s.iterator();

  11.                         while (iterator.hasNext()) {

  12.                                 sum += iterator.next().get();// 计算总分

  13.                                 count++;// 统计总的科目数

  14.                         }

  15.                         long average = (long) sum / count;// 计算平均成绩

  16.                         ctx.write(k2, new LongWritable(average));
  17.                         Counter countPrint1 = ctx.getCounter("Redue调用次数","空");
  18.                         countPrint1.increment(1l);

  19.                 }

  20.         }
复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多