public static class ActorCombiner extends Reducer<Text, Text, Text, Text> {
private Text text = new Text();
@Override
public void reduce(Text key, Iterable<Text> values, Context context)throws IOException, InterruptedException {
System.out.println("—————————ActorCombiner———————数据进入————————————————");
int maxHotIndex = Integer.MIN_VALUE;
int hotIndex = 0;
String name="";
for (Text val : values) {
System.out.println("————————————————开始循环————————————————");
String[] valTokens = val.toString().split("\t");
hotIndex = Integer.parseInt(valTokens[1]);
if(hotIndex>maxHotIndex){
name = valTokens[0];
maxHotIndex = hotIndex;
}//所有数据会先进行完for循环后,输出一个期望value
}
text.set(name+"\t"+maxHotIndex);
context.write(key, text);
System.out.println("—————————ActorCombiner———————combine完毕————————————————");
}
}
其实combiner 就是一个在map端运行的一个小型reducer,能减少数据的传输。运行过程:
- —————————ActorCombiner———————数据进入————————————————
- ————————————————开始循环————————————————
- ————————————————开始循环————————————————
- ————————————————开始循环————————————————
- ……
- ……
- ————————————————开始循环————————————————
- ————————ActorCombiner———————数据处理完毕————————————————
数据是以一个分片一个分片进入combiner里面的,一个分片流程只进行一次,而不是像map一样一行一行地循环进行,而是一个分片直接进行一次,所以这个分片的value把for循环进行完后,再输出一个value,而不是输出多个。所以谓之“合并”,是通过一个方法(如循环 比较 循环相加 循环求平均值)去获得对应的处理完的value。
reducer也同理,一个grouping分组完后,调用reduce来处理这组相同key的value。
所以Mapreduce就是按需求把key整合好给reducer,让reducer去针对相同的key,去处理不同的value,得出期望值。