1 ,官网解释 : 规约
每一个 map 都可能会产生大量的本地输出,Combiner 的作用就是对 map 端的输出先做一次合并,以减少在 map 和 reduce 节点之间的数据传输量,以提高网络IO 性能,是 MapReduce 的一种优化手段之一。
2 ,孙老师解释 : 规约
在 map 阶段的 reduce 操作:每一个分几期能算的先算一下,然后再发送给 reduce 统一计算,这样会减少 reduce 的任务量。
3 ,规约 :原理
4 ,规约 :适合做什么,不适合做什么
不适合做平均值,因为会丢失数据。
5 ,慎用 :
- 如果使用错误,不仅不能提高效率,反而会是计算结果错误。
- 不是所有的算法都适合使用Combiner处理,例如求平均数。
6 ,规约应用 wc :map
package day02.cbn;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class CbnMapper extends Mapper<LongWritable,Text,Text,IntWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// 每一行的数据都切开,得到字符串数组
String[] arr = value.toString().split(" ");
for (String s : arr) {
// 需要把普通类型转化成序列化类型
context.write(new Text(s),new IntWritable(1));
}
}
}
7 ,combiner :
package day02.cbn;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
// k2,v2,k2,v2
public class CbnCbn extends Reducer<Text,IntWritable,Text,IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int i = 0;
for (IntWritable v : values) {
i+=v.get();
}
context.write(key,new IntWritable(i));
}
}
8 ,reduce :
package day02.cbn;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
// k2,v2,k3,v3
public class CbnReduce extends Reducer<Text,IntWritable,Text,IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int i = 0;
for (IntWritable v : values) {
i+=v.get();
}
context.write(key,new IntWritable(i));
}
}
9 ,job :
package day02.cbn;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class CbnJob extends Configured implements Tool {
@Override
public int run(String[] strings) throws Exception {
// 指定主类
Job job = Job.getInstance(super.getConf(), "wc");
job.setJarByClass(this.getClass());
// 1 ,输入
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,new Path("C:\\Users\\86182\\Desktop\\hadoop\\day02 -- javaAPI 操作 hdfs -- hdfs 原理 -- mr 操作\\04 -- mr\\aa.txt"));
// 2 ,map
job.setMapperClass(CbnMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
// 3 ,分区
// 4 ,排序
// 5 ,规约
job.setCombinerClass(CbnCbn.class);
// 6 ,分组
// 7 ,reduce
job.setReducerClass(CbnReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 8 ,输出 ( 必须写一个不存在的路径 )
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,new Path("C:\\Users\\86182\\Desktop\\hadoop\\day02 -- javaAPI 操作 hdfs -- hdfs 原理 -- mr 操作\\04 -- mr\\out01"));
// 执行
boolean b = job.waitForCompletion(true);
// true-0;false-1
return b?0:1;
}
public static void main(String[] args) throws Exception {
int i = ToolRunner.run(new Configuration(), new CbnJob(), args);
System.exit(i);
}
}
10 ,执行结果 :
没有什么不同