<span style="font-family:Microsoft YaHei;">工作需要,最近在学习Hadoop,看了下关于MapReduce和HDFS的工作机制和原理,打算后续认真读读MapReduce的源码,和Hadoop的深入学习。</span>
<span style="font-family:Microsoft YaHei;">这是随手记,方便自己以后查找,而且也希望给其他朋友一点参考,哈哈!</span>
import java.io.IOException;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
/**
* 记录去重功能
*/
public class removeDeplicate {
/**
* mapper中,把输入中的value转换为输出的key
*/
public static class mapper extends Mapper<Object, Text, Text, Text> {
public void map(Object key, Text value, Context context){
System.out.println("======map=====" + key + " -- " + value);
try {
context.write(value, new Text(" ") );
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* reducer中得到的是从mapper输出,而且进行分区后的数据。
* 只要输出每个reduce里的key值就可以
*/
public static class reducer extends Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterable<Text> values, Context context){
System.out.println("======reduce====== " + key );
for(Text value : values) {
System.out.println(" " + value);
}
try {
context.write(key, new Text(" "));
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@SuppressWarnings("deprecation")
public static void main( String []args ) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration(); //作用是什么还不清楚,貌似它能干的,在job中都干了。留待后续研究。
Job job = new Job(conf, "removeDeplicate"); //查看源码发现,job的传参第二项可以把name传入,配置作业的名字
//job继承jobContext, jobContext中有个子类conf,所需的所有配置信息,包括conf, class, path等等都是在conf中进行配置。
//在没有指定载入的配置信息的情况下,job默认载入hadoop的core-default.xml, hdfs-default.xml, mapred-default.xml
String[] elements = new GenericOptionsParser(conf, args).getRemainingArgs(); //可以理解为提取args中的元素,具体操作比较复杂,还涉及到conf的设置。待看
//指定jar包的来源class
job.setJarByClass(removeDeplicate.class);
//输入格式设置: 采用默认输入格式
//对mapper的设置
job.setMapperClass(mapper.class);
//指定mapper的输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
//指定partitionor: 不指定,使用默认partitionor,按照key分区
//对reducer的配置; 再试试setNum的作用
job.setNumReduceTasks(4); //本程序中,这个设置无效。我觉得应该这个要和自定义的partitionor配合使用。
job.setReducerClass(reducer.class);
//指定reducer的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); //actually this element is none
//输出格式设置: 不设置,采用默认的text格式输出
//指定输入输出路径,老版本中是conf中配置,新版本直接通过fileinput/outputformat配置
FileInputFormat.addInputPaths(job, elements[0]);
FileOutputFormat.setOutputPath(job, new Path(elements[1]));
//System.out.println( JSONObject.fromObject(job).toString());
//作业提交执行,相当于旧版本中的jobclient.runjob()
job.waitForCompletion(true);
}
}