MapReduce用例代码的编写流程
1)函数入口
①首先创建配置对象Configuration,用于加载配置文件的信息;
②创建一个Job对象,通过getInstance()函数设置当前main函数所在的类,设置后运行代码可以找到函数的入口;
③设置MapReduce的输入输出路径用于输入数据和输出计算的数据结果; 注意若要是输出的路径在集群中已经存在,需要操作HDFS进行判断与删除,在此处要建立一个HDFS的FileSystem对象。
④设置map端,确定map的class以及map端的输出的key和value的类型;
⑤设置Reduce的class,可以设置reduceTask的数量
⑥job对象设置waitForCompletion,设置为true打印MapReduce的执行信息。
2)Map端的函数编写
①类输入的参数类型为:block的偏移量;输入的内容(其类型都是hadoop专有的类型分别为LongWritable,Text)。类输出的类型为:Text和IntWritable。
②重写map函数,编写逻辑对数据进行清洗和处理成reduce端能接收的数据。
3)Reduce端函数编写
①类输入的参数类型受map端输出类型的影响,map端输出什么类型的数据,reduce端接收什么类型的数据
②reduce端重写reduce方法,对数据进行进一步的处理,得到想要的结果,通过context.write写出数据。
例子代码(WordCount字数统计小demo)
main函数类:
public class WC {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration(true);
Job job = Job.getInstance(conf);
//设置当前main函数所在类
job.setJarByClass(WC.class);
job.setJar("d:/wc.jar");
//设置输入路径
FileInputFormat.setInputPaths(job, "/input/wc");
//设置输出路径
Path outputPath = new Path("/output/");
FileSystem fs = outputPath.getFileSystem(conf);
if(fs.exists(outputPath)){
fs.delete(outputPath,true);
}
FileOutputFormat.setOutputPath(job, outputPath);
//设置Map class
job.setMapperClass(WCMapper.class);
//设置map输出key、value的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//设置reduce class
job.setReducerClass(WCReduce.class);
job.setNumReduceTasks(2);
job.waitForCompletion(true);
}
}
map类
public class WCMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
Text myKey = new Text();
IntWritable myValue = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
System.out.println(key+"==========");
// value.toString().split(" ")
String[] words = StringUtils.split(value.toString(), ' ');
for (String word : words) {
myKey.set(word);
context.write(myKey,myValue);
}
}
}
reduce类
public class WCReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
context.write(key, new IntWritable(sum));
}
}
MapReduce代码编写总结:
1.自定义对象时要实现WritableComparable接口
要实现序列化和反序列化方法以及CompareTo方法
2.实现Mapper类要继承Mapper抽象类
3.实现Reduce类要继承Reduce抽象类
4.自定义分组器要继承一个WritableComparator抽象类,还要调用构造函数
5.自定义排序器要继承WritableComparator抽象类
6.自定义分区器要继承一个partioner抽象类
7.combiner可以直接指向reduce.class,因为都是小聚合,实现类似