第一个MapreducerDriver跑起来

注:由Hadoop权威指南开始的

MapReducer的用途是数据的存储和分析,就像lucene一样要想有个完整的可以运行起来的搜索引擎肯定要构建索引,然后根据client端的需求进行数据分析一样。

1,Mapper

这里Mapper是一个泛型类,前两位参数为输入类型,后两位参数为输出类型(与reducer的输入类型必须对应)。当前temperatureMapper的输入Key,value的类型分别为LongWritable, Text,输出key,value类型分别为Text, IntWritable。在这里需要主义的是通过符合特定业务的逻辑对数据进行有选择的采集筛选


public class MaxTemperatureMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable>{

@Override
public void map(LongWritable key, Text value,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException {
// TODO Auto-generated method stub
String line = value.toString();
String year = line.substring(15,19);
int airTemperature = Integer.parseInt(line.substring(88,92));
System.err.println("text=" + year + " intWritable=" + airTemperature);
output.collect(new Text(year), new IntWritable(airTemperature));
}

}

2,reducer
   这里reducer的参数与上面的解释相似,这里需要对数据进行分析,也就是说于业务相关了。

public class MaxTemperatureReducer extends MapReduceBase
implements Reducer<Text, IntWritable, Text, IntWritable>{

@Override
public void reduce(Text key, Iterator<IntWritable> values,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException {
// TODO Auto-generated method stub
int maxValue = Integer.MIN_VALUE;
while(values.hasNext()){
maxValue = Math.max(maxValue, values.next().get());
}
System.err.println("key= " + key + " maxValue=" + maxValue);
output.collect(key, new IntWritable(maxValue));

}

}

3,driver
public int run(String[] args) throws Exception {
// TODO Auto-generated method stub
if(args.length != 2){
System.err.printf("Usage: %s[generic options] <input> <output>\n", getClass().getSimpleName());
}
JobConf conf = new JobConf(this.getConf(), this.getClass());
                //必须为目录,文件系统会到相应的目录读取数据,但是目录不能递归
FileInputFormat.addInputPath(conf, new Path(args[0]));
                //必须为目录,且不能存在由hadoop生成,recuder声称的数据会保存在特定规则文件中
FileOutputFormat.setOutputPath(conf, new Path(args[1]));

conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);

conf.setMapperClass(MaxTemperatureMapper.class);
conf.setCombinerClass(MaxTemperatureReducer.class);
conf.setReducerClass(MaxTemperatureReducer.class);

JobClient.runJob(conf);

return 0;
}

public static void main(String [] args)throws Exception{
int exitCode = ToolRunner.run(new MaxTemperatureDriver(), args);
System.exit(exitCode);
}

运行的时候将class文件拷贝到 hadoop_home目录下,然后在命令行运行
$hadoop ***.***.Map*Driver -fs fs:/// -jt local in out
以上表示在本地文件系统(当然使用HDFS也是可以的)模式下,运行Mpa*Driver,读取目录in中的文件,将结果数据保存到out(out目录由hadoop生成,否则会报告fileExist错误)目录中

hadoop com.awen.mapreduce.MaxTemperatureDriver -fs file:/// -jt local in out
当然以上命令也可以有另一种形式:就是通过hadoop *** -conf ***命令覆盖configuration

out目录存在的话:
Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory file:/opt/hadoop-0.20.2/out already exists


下面将文件系统修改为hdfs文件系统
首先从本地文件系统中将数据拷贝到hdfs系统中的当前用户下的in目下的temperature文件中
hadoop fs -copyFromLocal /opt/hadoop*/in/temperature in/temperature

运行
hadoop com.awen.mapreduce.MaxTemperatureDriver in out

这次会发现在本地伪分布式的模式下用hdfs文件系统的速度运行起来比本地文件系统要满很多很多……那么这个问题只能在HDFS部分分析了,呵呵

猜你喜欢

转载自awenhaowenchao.iteye.com/blog/737736