要学习的第一个MapReduce当然是wordcount,不过官方已经给出源代码和足够的解释,详见:http://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Example%3A+WordCount+v1.0
首先,默认hadoop所用的eclipse已经配置好(可以考虑记录eclipse配置)
首先建立一个文件test.txt,数据如下:
Apr 23 11:49:54 hostaod: wlan0: STA 14:7d:c5:9e:fb:84
Apr 23 11:49:53 hostapd: wlan0: STA 74:e6:0b:04:28:f2
Apr 23 11:49:52 hostapd: wlan0: STA cc:af:78:cc:d5:5d
Apr 23 11:49:50 hostapd: wlan0: STA cc:ad:78:cc:d5:5d
Apr 23 11:49:44 hostapd: wlan0: STA 74:e6:0b:04:28:f2
Apr 23 11:49:43 hostapd: wlan0: STA 74:e6:0b:04:28:84
Apr 23 11:49:42 hostapd: wlan0: STA 14:e6:0b:04:28:f2
可以看到,这是一组有规律的数据记录,现在需要对这组数据进行处理,筛选出其中的日期和后面的端口数据,模仿wordcount进行代码编写。
这里要注意的是,在代码编写过程中,configuration包和tool包不只有org.apache.hadoop中存在,所以需要注意包的导入,最好的方式是牺牲一些效率,直接把整个包导进去(下面的代码就采用这种做法),熟练后在分别导入。
这次的代码,只有Map程序而没有Reduce程序,是一个简单版的demo,甚至比wordcount还简单的。
再有,此处的MapReduce是新版的API,不同之处就在于mapper的参数有些改动,以后会详细比较。
代码如下:
import java.io.*;
import java.util.*;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.*;
import org.apache.hadoop.mapreduce.lib.output.*;
import org.apache.hadoop.util.*;
public class test_1 extends Configured implements Tool{
enum Counter{
LINESKIP,//error line
}
public static class Map extends Mapper<LongWritable,Text,NullWritable,Text>{
public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException{
String line=value.toString();//read source line
try{
String[] lineSplit=line.split(" ");
String month=lineSplit[0];
String time=lineSplit[1];
String mac=lineSplit[6];
Text out=new Text(month+' '+time+' '+mac);
context.write(NullWritable.get(), out);//key \t value
}
catch(java.lang.ArrayIndexOutOfBoundsException e){
context.getCounter(Counter.LINESKIP).increment(1);
return;
}
}
}
public static void main(String[] args) throws Exception{
int ret = ToolRunner.run(new Configuration(), new test_1(), args);
System.exit(ret);
}
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
Job job=new Job(conf,"test_1");
job.setJarByClass(test_1.class);
job.setJobName("test_1");
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(Text.class);
job.setMapperClass(Map.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
boolean success = job.waitForCompletion(true);
return success ? 0:1;
}
}
接着,要对Run Configurations进行 一些配置,如下:
参数自然也要配置,分别是输入文件和输出文件的路径,要注意的是,输出文件路径所写着的output文件夹是不允许存在的,如有存在需要手动删除,否则会报错。
Run,输出可得: