mapreduce程序编写规范

来源:互联网 发布:淘宝下拉推广 编辑:程序博客网 时间:2024/05/14 09:45

1:用户编写的程序分成三个部分:Map,Reducer,Driver(用户提交mr程序的客户端)
2:map的输入数据是KV对的形式(kv的类型可以自定义)
3:map的输出数据是KV对的形式(kv的类型可以自定义)
4:map中的业务logic写在map()方法中
5:map方法对每一个《k,v》调用一次
6:Reducer的输入数据类型对应Mapper的输出类型,也是KV
7:Reducer的业务logic写在reduce()方法中
8:Reducer方法对每一组相同的《k,v》调用一次
9:map和reducer都需要继承各自的父类
10:整个程序需要一个driver来进行提交,提交描述各种必要信息的job对象

整体思路上就是先确定传输的key,再确定传输的value,
一般value是实现了writeable接口的对象(反系列化时,需要反射,所以value的bean需要是有空参构造

        context.write(new Text(phoneNumber),new FlowBean(Long.parseLong(UpFlow),Long.parseLong(downFlow)));

web端写日志时,要一行信息即可封装成一个java对象,然后每个字段有特定的位置,这样mapreduce程序就可以这样来取

 String phoneNumber = fileds[0]; String UpFlow = fileds[fileds.length-3]; String downFlow = fileds[fileds.length-2];

以上就是取数据的方式

       Long sum_upFlow = 0L;        Long sum_DownFlow = 0L;        for (FlowBean value : values) {            sum_upFlow += value.getUpFlow();            sum_DownFlow += value.getDownFlow();        }        FlowBean out = new FlowBean(sum_upFlow,sum_DownFlow)        context.write(key,out);

最后mapreduce的结果写入文件时,调用对象的tostring方法,所以要重写FlowBean的ToString方法

二:关于数据分区
1:map数据产生后,通过OutputCollect对象写如一个分区区域的文件中,默认分区的算法是对map输入的key取hash值,这就是为什么在reducer中拿到的是一组相同的key。
2:重写分区方法,例如我要将上诉流量按省份分区,然后保存在不同的文件中,该怎么实现呢?

 public class ProvicePartitioner extends Partitioner<Text,FlowBean>{    private static HashMap<String,Integer> provinces = new HashMap<>();    static {        //该段代码理应是链接数据库的        provinces.put("136",0);        provinces.put("137",1);        provinces.put("138",2);        provinces.put("139",3);    }    @Override    public int getPartition(Text text, FlowBean flowBean, int i) {        String prefix = text.toString().substring(0,3);        //确定分区条件        Integer provinceId = provinces.get(prefix);        //返回结果有0,1,2,3,4所以分成了5个区        return provinceId==null?4:provinceId;    }}

5个区说明应该有5个reducer进行处理
所以Driver中应该添加代码

 //设置分区条件和对应数量的reducer   job.setPartitionerClass(ProvicePartitioner.class);   job.setNumReduceTasks(5);
0 0
原创粉丝点击