reduce累加实现

  与map端的模式类似,map端要重写Mapper方法,reduce端也要重写Reduce方法,这里有一个泛型,我们先看参数类型

 

 

 分别对应输入keyin,valuein,keyout,valueout.。

  这里前两个参数:keyin,valueint就是map端处理以后的键值对。map端的逻辑我们已经写完了,在那个阶段,我们设置了以手机号为key,一个bean对象为value的键值对。但是map端还有其他的处理逻辑,设置完键值对以后,map还要把相同key的数据放在一起,打上分区标志(如果有分区的话),然后把相同分区的数据分发(shuffle)一个reduce里面。比如我们的原始数据有这么两个手机号:

13726230503112 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200

13726230503112 5C-0E-8B-C7-F7-90:CMCC 120.197.40.4 rank.ie.sogou.com 搜索引擎 28 27 3659 3538 200,

  map端处理完以后,分发到reduce的数据格式是这样一个map集合:

map(

key:13726230503112 

value{

  phoneNumber:13726230503112 ,upFlow:2481  downFlow:24681 ,sumFlow:27162

  phoneNumber:13726230503112 ,upFlow:3659 downFlow:3538 ,sumFlow:7179

}

)

 

 

 

reduce代码:

package MR.phone;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class FlowReduce extends Reducer<Text,PhoneBean,Text,PhoneBean> {
@Override
protected void reduce(Text key, Iterable<PhoneBean> values, Reducer<Text, PhoneBean, Text, PhoneBean>.Context context) throws IOException, InterruptedException {
//遍历所有的PnoneBean,将其上下行流量进行累加计算,计算完之后封装数据,写出
long sum_upflow=0;
long sum_downflow=0;
long sum_flow=0;
for (PhoneBean flow : values) {
sum_upflow=sum_upflow+flow.getUpFlow();
sum_downflow=sum_downflow+ flow.getDownFlow();
sum_flow=sum_flow+flow.getSumFlow();
}
//封装数据,写出
PhoneBean result_flow=new PhoneBean(sum_upflow,sum_downflow,sum_flow);
context.write(key,result_flow);

}
}

这里的代码逻辑计较简单,注意我们这里封装valueout的时候,用的有参构造, 注意bean里面要有有参构造。但是整个一个map——shuffl——reduce过程基本就是这样了。现在回过头看map-reduce的流程图,会清晰很多。

现在剩下的问题就是搞个Driver(固定套路),测试一下我们的代码逻辑:

package MR.phone;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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;

import java.io.IOException;

public class FlowDriver {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
//1,获取配置信息,设置job
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);

//设置job
job.setJarByClass(FlowDriver.class);

//设置map
job.setMapperClass(FlowMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(PhoneBean.class);

//设置reduce
job.setReducerClass(FlowReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(PhoneBean.class);

//设置路径
FileInputFormat.setInputPaths(job,new Path("D:\\bigadatapra\\phone_data.txt"));
FileOutputFormat.setOutputPath(job,new Path("D:\\bigadatapra\\output041801"));

//提交job
boolean result = job.waitForCompletion(true);

System.exit(result?0:1);

}

}

如果配置好本地Hadoop环境的话,直接运行main函数就能看见结果了。

 

 

 





posted @ 2022-04-18 11:26  码码小菜鸟  阅读(412)  评论(0)    收藏  举报