mapreduce是hadoop生态中非常重要的一部分,顾名思义,主要分为两部分,map和reduce,他们各司其职,map的主要功能是用来对待处理的文档进行处理,主要是对数据进行按行读取,分割,然后根据用户需要进行不同的判断,清晰,直到得到目标的干净数据。reduce程序主要是对map传来的数据进行汇总,求和。最后经统计的结果输入到目标文件中。具体代码如下:
WCMapper.java
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
//4个泛型,前两个是mapper输入数据的类型KENY是输入的key的类型,VALUIN是指的value的类型
//map和reduce的数据的输入输出都是以key-value的形式存在的
//默认情况下框架传递给我们的mapper框架输入数据,key是要处理文本的中一行的起始位置的偏移量,这一行的内容作为value
public class WCMapper extends Mapper {
//mapredure框架每度一行数据就会调用一次方法,递归调用
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
//具体业务逻辑写在这个方法中,而且我们要处理的数据已经被框架传递进来,在方法的key-value参数中
//key这一行数据的其实偏移量 value是这一行的内容
//将这一行的内容转换为String类型
String line = value.toString();
//将这一行内容进行分割
String[] words = StringUtils.split(line," ");
//遍历数组,以k-v的形式 k:单词 v:1
for(String word : words) {
context.write(new Text(word),new LongWritable(1));
}
}
}
WCReducer.java
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WCReducer extends Reducer{
//map的数据处理完成之后对,将所有的kv对缓存起来,进行分组,然后传递一个分组,调用一次reduce
//
@Override
protected void reduce(Text key, Iterable values,Context contest) throws IOException, InterruptedException {
long count = 0;
//遍历valueslist,进行累加求和
for(LongWritable value:values) {
count +=value.get();
}
//输出一个文件的统计结果
contest.write(key,new LongWritable(count));
}
}
WCRunner.java
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WCRunner {
//用来描述一个特定的job,比如改作业指定那个类是逻辑处理中的map,那个类是逻辑处理中发的reduce
//还可以指定改作业要处理的数据的所在的路径
//还可以指定作业完成后输出结果放到的哪个路径中
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
//设置整个job所要用到的jar包的类所在的位置
job.setJarByClass(WCRunner.class);
//本job所使用的mapper和reduce
job.setMapperClass(WCMapper.class);
job.setReducerClass(WCReducer.class);
//指定reduce的kv类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//指定map的kv类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//指定元数据指定在哪里
//这里的文件路径既可以windows中的文件路径,也可以是hdfs中的路径,前提是可以互相通讯
FileInputFormat.setInputPaths(job,new Path("/home/hadoop/data-shixun/wordcount/srcdata.txt"));
FileOutputFormat.setOutputPath(job, new Path("/home/hadoop/data-shixun/wordcount/output"));
//将job提交给集群
job.waitForCompletion(true);
}
}
代码中相应部分都有详细的注释。