黑猴子的家:MapReduce流量汇总程序案例二

将统计结果按照手机归属地不同省份输出到不同文件中(Partitioner)

1、分析

(1)Mapreduce中会将map输出的kv对,按照相同key分组,然后分发给不同的reducetask。默认的分发规则为:根据key的hashcode%reducetask数来分发

(2)如果要按照我们自己的需求进行分组,则需要改写数据分发(分组)组件Partitioner
自定义一个CustomPartitioner继承抽象类:Partitioner

(3)在job驱动中,设置自定义partitioner: job.setPartitionerClass(CustomPartitioner.class)

2、在流量汇总程序案例一的基础上,增加一个分区类

import java.util.HashMap;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

/**
 * K2 V2 对应的是map输出kv类型
* @author Administrator
*/
public class ProvincePartitioner extends Partitioner {
    @Override
    public int getPartition(Text key, FlowBean value, int numPartitions) {
        // 1 获取电话号码的前三位
        String preNum = key.toString().substring(0, 3);
        
        int partition = 4;
        
        // 2 判断是哪个省
        if ("136".equals(preNum)) {
            partition = 0;
        }else if ("137".equals(preNum)) {
            partition = 1;
        }else if ("138".equals(preNum)) {
            partition = 2;
        }else if ("139".equals(preNum)) {
            partition = 3;
        }
        return partition;
    }
}

3、在驱动函数中增加自定义数据分区设置和reduce task设置

public static void main(String[] args) throws Exception {
        // 1 获取配置信息,或者job对象实例
        Configuration configuration = new Configuration();
        Job job = Job.getInstance(configuration);

        // 6 指定本程序的jar包所在的本地路径
        job.setJarByClass(FlowCount.class);

        // 8 指定自定义数据分区
        job.setPartitionerClass(ProvincePartitioner.class);
        
        // 9 同时指定相应数量的reduce task
        job.setNumReduceTasks(5); 
        
        // 2 指定本业务job要使用的mapper/Reducer业务类
        job.setMapperClass(FlowCountMapper.class);
        job.setReducerClass(FlowCountReducer.class);

        // 3 指定mapper输出数据的kv类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(FlowBean.class);

        // 4 指定最终输出的数据的kv类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(FlowBean.class);

        // 5 指定job的输入原始文件所在目录
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 7 将job中配置的相关参数,以及job所用的java类所在的jar包, 提交给yarn去运行
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }

4、将程序打成jar包,然后拷贝到hadoop集群中。

flowcountPartitionser.jar 

5、启动hadoop集群

[victor@hadoop102 hadoop]$ sbin/start-all.sh 

6、执行flowcountPartitionser程序

[victor@hadoop102 hadoop]$ hadoop jar flowcountPartitionser.jar \
com.victor.mr.partitioner.FlowCount \
/user/victor/flowcount/input /user/victor/flowcount/output

7、查看结果

[victor@hadoop102 software]$ hadoop fs -lsr /
/user/victor/flowcount/output/part-r-00000
/user/victor/flowcount/output/part-r-00001
/user/victor/flowcount/output/part-r-00002
/user/victor/flowcount/output/part-r-00003
/user/victor/flowcount/output/part-r-00004

8、Code -> GitHub

https://github.com/liufengji/hadoop_mapreduce.git

你可能感兴趣的:(黑猴子的家:MapReduce流量汇总程序案例二)