|
今天不是什么新的内容,主要介绍下0.20版本下hadoop的调试、计数器、调试信息输出等内容。
相信很多人学习hadoop都是从hadoop权威指南开始的,但权威指南使用的hadoop版本是0.19版本的,而有部分人(其中包括我)使用的0.20版本的。相信大家都知道0.20版本相对于0.19版本有了重大的改变。提供了一系列新的API。具体哪些我这里就不具体说了。其中一个跟测试、调试密切相关的就是在0.20版本出现了Context object(上下文对象).所以本篇日志就记录一下我在0.20版本下的测试、调试程序。这里有要特别提示下,这些方法都是我自己摸索的,不敢保证一定效果最好或者最简洁,比如计数器那个我也见过其他实现方法。所以如果有错请大家指出。先谢谢了。
先来说说测试,老规矩直接上代码,注释在代码里:
public class TestMapper {@Testpublic void processReduce() throws IOException{wordcountReduce reuder = new wordcountReduce(); //reduce测试LongWritable key = new LongWritable(1234);List<LongWritable> list = new ArrayList<LongWritable>();list.add(new LongWritable(10));list.add(new LongWritable(2));Iterable<LongWritable> values = list; //构造Iterable//OutputCollector<LongWritable, LongWritable> output = mock(OutputCollector.class); 老版本测试Reducer.Context context = mock(Reducer.Context.class); //这里要注明Reduce.context上下文对象try {//reude.reduce(key, values, output, null); 老版本测试reuder.reduce(key, values, context); //使用上下文对象代替上面的outputverify(context).write(new LongWritable(12), new LongWritable(1234));}catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Testpublic void processMap()throws IOException{wordcountMapper mapper = new wordcountMapper(); //map测试Text value = new Text("1234");LongWritable key = new LongWritable(1);//OutputCollector<LongWritable, Text> output = mock(OutputCollector.class); 老版本测试Mapper.Context context = mock(Mapper.Context.class);try{//mapper.map(key, value, output, null); 老版本测试mapper.map(key, value, context);verify(context).write(new LongWritable(1234), new LongWritable(1));} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static class wordcountMapper extendsMapper<LongWritable, Text, LongWritable, LongWritable>{public void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException{String one = value.toString();context.write(new LongWritable(Integer.parseInt(one)) , key);}}public class wordcountReduce extendsReducer<LongWritable, LongWritable, LongWritable, LongWritable>{public void reduce(LongWritable key, Iterable<LongWritable>values, Context context)throws IOException, InterruptedException{int sum = 0;for (LongWritable str : values){sum += str.get();}context.write(new LongWritable(sum), key );}}}
接着来讨论下hadoopp的调试信息,我介绍两种:计数器、直接打印调试信息
这里我只给出主要代码,main函数里面的代码十分简单,我就不给出了。
public static class wordcountMapper extendsMapper<LongWritable, Text, Text, IntWritable>{enum Temper{OVER_100} //使用权威指南里的方法定义枚举类型private final static IntWritable one = new IntWritable(1);private Text word = new Text();public void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException{String line = value.toString();StringTokenizer itr = new StringTokenizer(line);while(itr.hasMoreElements()){word.set(itr.nextToken());context.write(word, one);}System.out.println("map"); //直接打印调试信息。context.setStatus("this kk!!"); //设置状态Counter c = context.getCounter(Temper.OVER_100); //通过context直接获取计数器这个跟0.19版不一样c.increment(1); //计数器加一}}public static class wordcountReduce extendsReducer<Text, IntWritable, Text, IntWritable>{public void reduce(Text key, Iterable<IntWritable>values, Context context)throws IOException, InterruptedException{int sum = 0;for (IntWritable str : values){sum += str.get();}context.write(key, new IntWritable(sum));System.out.println("reduce"); //直接打印调试信息}}
使用上面代码的效果,我现在来给大家指出:
1:我们上面使用了计数器,当我们提交作业运行完成后,可以通过namenode返回的信息查看计数器的值
当然我也可以通过hadoop提供的web页面查看计数器的值
当然我们也可以查看每个map里计数器的取值。
我前两天看了一篇文章,也是在0.20中使用计数器的,那篇文章中说的是可以直接使用
Counter c = context.getCounter("Counter","Counter1");来设置计数器,应该有可以。这里就算多提供了一种使用计数器的方法。
2: 我们程序中使用了System.out.println("map"); System.out.println("reduce"); //直接打印调试信息。
这里我也有两种查看方式,一种是在web页面中查看
还有一种是直接在datanode的log目录下查看
具体路径是 hadoop-0.20/logs/userlogs/attempt-*****-*****/stdout文件中查看
3:程序中我们还使用了context.setStatus("this kk!!"); //设置状态
这个也是在web中可以查看
今天这篇文章没什么技术含量。就当对新版本的学习了。 |
|
|