最近一直再看《hadoop in action》这本书,这本书整体讲的不错,就是hadoop不同版本之间的区别比较大,大家学习时一定要用统一版本,否则事倍功半。
书上第4章第四节讲的是版本间的区别,我这里简单整理一下:
去hadoop的官网可以找到如下信息:
- 1.0.X - current stable version, 1.0 release
- 1.1.X - current beta version, 1.1 release
- 2.X.X - current alpha version
- 0.23.X - simmilar to 2.X.X but missing NN HA.
- 0.22.X - does not include security
- 0.20.203.X - old legacy stable version
- 0.20.X - old legacy version
写作时间:2013-3-10 16:25
这说明hadoop的发展还是挺快的,有各种各样的版本,alpha beta stable都有,这也说明了开源的hadoop是广大程序员处理大数据的首选。
书上说最稳定的版本是0.18.3,但是鉴于这本书写与09年,所有这个参考价值不是很大。但是0.20这个版本是个承上启下的版本,它对于老版本的api全部支持,只是标注了deprecated的,但是0.20之后的版本直接就把老的api给删去了,0.20同时也很好的支持新发布版本的api,所以这个版本可以用来学习使用。
0.20之前版本中,org.apache.hadoop.mapred包中的内容在新版本被移除了,放在了org.apache.hadoop.mapreduce这个新包中,许多类都在org.apache.hadoop.mapreduce.lib包中。如果我们使用了0.20以后的版本,我们就不能引用org.apache.hadoop.mapred包中的类了。
在新版本中,最有意义的变化是引入了context这个类,它可以代替OutputCollector和Reporter这两个对象。
在新版本中,map()函数和reduce()被放到了抽象类Mapper和Reducer类中,这两个抽象类代替了org.apache.hadoop.mapred.Mapper和org.apache.hadoop.mapred.Reducer这两个接口。同时也代替了MapReduceBase这个类。
在新版本中,JobConf和JobClient被移除了。它们的功能被放到Configuration类和新增的Job类中去了(Configuration以前是JobConf的父类)。Configuration类只是用来配置一个job,而Job类用来定义和控制job的运行。
下面给出一些老版本与新版本代码,以后大家些hadoop程序就可以按照这个模板了。
先给出老版本的代码:
1. package com.ytu.old;
2.
3. import java.io.IOException;
4. import java.util.Iterator;
5.
6. import org.apache.hadoop.conf.Configuration;
7. import org.apache.hadoop.conf.Configured;
8. import org.apache.hadoop.fs.Path;
9. import org.apache.hadoop.io.Text;
10. import org.apache.hadoop.mapred.FileInputFormat;
11. import org.apache.hadoop.mapred.FileOutputFormat;
12. import org.apache.hadoop.mapred.JobClient;
13. import org.apache.hadoop.mapred.JobConf;
14. import org.apache.hadoop.mapred.KeyValueTextInputFormat;
15. import org.apache.hadoop.mapred.MapReduceBase;
16. import org.apache.hadoop.mapred.Mapper;
17. import org.apache.hadoop.mapred.OutputCollector;
18. import org.apache.hadoop.mapred.Reducer;
19. import org.apache.hadoop.mapred.Reporter;
20. import org.apache.hadoop.mapred.TextOutputFormat;
21. import org.apache.hadoop.util.Tool;
22.
23. public class MyOldJob extends Configured implements Tool {
24.
25. public static class MapClass extends MapReduceBase implements
26. Mapper<Text, Text, Text, Text> {
27.
28. @Override
29. public void map(Text key, Text value, OutputCollector<Text, Text> output,
30. throws IOException {
31. // TODO Auto-generated method stub
32. output.collect(value, key);
33. }
34.
35. }
36. public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
37.
38. @Override
39. public void reduce(Text key, Iterator<Text> values,
40. OutputCollector<Text, Text> output, Reporter reporter)
41. throws IOException {
42. // TODO Auto-generated method stub
43. "";
44. while(values.hasNext()) {
45. if (csv.length()>0) {
46. ",";
47. }
48. csv+=values.next().toString();
49. }
50. new Text(csv));
51. }
52.
53. }
54. @Override
55. public int run(String[] args) throws Exception {
56. // TODO Auto-generated method stub
57. this.getConf();
58. new JobConf(conf, MyOldJob.class);
59.
60. new Path(args[0]));
61. new Path(args[1]));
62.
63. "MyOldJob");
64. class);
65. class);
66.
67. class);
68. class);
69. class);
70. class);
71. "key.value.separator.in.input.line", ",");
72.
73. JobClient.runJob(job);
74.
75. return 0;
76. }
77. public static void main(String[] args) throws Exception {
78. int res = ToolRunner.run(new Configuration(), new MyOldJob(), args);
79. System.exit(res);
80. }
81.
82. }
然后在给出新版本的代码:
1. package com.ytu.new1;
2.
3. import java.io.IOException;
4.
5. import org.apache.hadoop.conf.Configuration;
6. import org.apache.hadoop.conf.Configured;
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.input.TextInputFormat;
15. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
16. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
17. import org.apache.hadoop.util.Tool;
18. import org.apache.hadoop.util.ToolRunner;
19.
20. public class MyNewJob extends Configured implements Tool {
21.
22. public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {
23. protected void map(LongWritable key, Text value, Context context)
24. throws IOException, InterruptedException {
25. ",");
26. new Text(citation[1]), new Text(citation[0]));
27. };
28. }
29.
30. public static class Reduce extends Reducer<Text, Text, Text, Text> {
31. protected void reduce(Text key, Iterable<Text> values, Context context)
32. throws IOException, InterruptedException {
33. "";
34. for (Text val : values) {
35. if (csv.length() > 0) {
36. ",";
37. }
38. csv += val.toString();
39. }
40. new Text(csv));
41. };
42. }
43.
44. @Override
45. public int run(String[] args) throws Exception {
46. // TODO Auto-generated method stub
47. this.getConf();
48.
49. new Job(conf, "MyNewJob");
50. class);
51.
52. new Path(args[0]));
53. new Path(args[1]));
54.
55. class);
56. class);
57.
58. class);
59. class);
60.
61. class);
62. class);
63. true)?0:1);
64. return 0;
65. }
66.
67. public static void main(String[] args) throws Exception {
68. int res = ToolRunner.run(new Configuration(), new MyNewJob(), args);
69. System.exit(res);
70. }
71. }
最后再说一点:
书上说KeyValueTextInputFormat这个类在0.20中被移除了,但是我现在用的是版本1.1.0.这个类照样可以用,但是如果要想设置分隔符的方式不一样,
mapreduce.input.keyvaluelinerecordreader.key.value.separator
key.value.separator.in.input.line
其他用法一样。