大数据学习12_MapReduce分区

MapReduce 分区

分区介绍:

在 MapReduce 中, 通过我们指定分区, 会将同一个分区的数据发送到同一个 Reduce 当中进行 处理 例如: 为了数据的统计, 可以把一批类似的数据发送到同一个 Reduce 当中, 在同一个 Reduce 当 中统计相同类型的数据, 就可以实现类似的数据分区和统计等 其实就是相同类型的数据, 有共性的数据, 送到一起去处理 Reduce 当中默认的分区只有一个

一张图看懂分区

分区代码编写

需求:将彩票中奖号码小于15的归到一个分区,大于15的归到另一个分区

 

 

 定义Mapper

public class PartitionMapper extends Mapper<LongWritable,Text, Text, NullWritable> {
    //map方法将K1和V1转为K2和V2
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //方式1:定义计数器
        Counter counter = context.getCounter("MR_COUNTER", "partition_counter");
        //每次执行该方法,则计数器变量的值加1
        counter.increment(1L);
        context.write(value,NullWritable.get());
    }
}

定义 Reducer 逻辑

public class PartitionerReducer extends Reducer<Text, NullWritable, Text,NullWritable> {
    public static enum  Counter{
        MY_INPUT_RECOREDS,MY_INPUT_BYTES
    }

    @Override
    protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
        //方式2:使用枚枚举来定义计数器
        context.getCounter(Counter.MY_INPUT_RECOREDS).increment(1L);
        context.write(key, NullWritable.get());
    }
}

自定义 Partitioner

public class MyPartitioner extends Partitioner<Text,NullWritable> {
    /*
          1:定义分区规则
          2:返回对应的分区编号
         */
    @Override
    public int getPartition(Text text, NullWritable nullWritable, int i) {
        //1:拆分行文本数据(K2),获取中奖字段的值
        String[] split = text.toString().split("\t");
        String numStr = split[5];

        //2:判断中奖字段的值和15的关系,然后返回对应的分区编号
        if(Integer.parseInt(numStr) > 15){
            return  1;
        }else{
            return  0;
        }
    }
}

Main 入口

public class JobMain extends Configured implements Tool {
    @Override
    public int run(String[] strings) throws Exception {
        //1:创建job任务对象
        Job job = Job.getInstance(super.getConf(), "partition_maperduce");

        //2:对job任务进行配置(八个步骤)
        //第一步:设置输入类和输入的路径
        job.setInputFormatClass(TextInputFormat.class);
        //TextInputFormat.addInputPath(job, new Path("hdfs://node01:8020/input"));
        TextInputFormat.addInputPath(job, new Path("file:///D:\\input"));
        //第二步:设置Mapper类和数据类型(K2和V2)
        job.setMapperClass(PartitionMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(NullWritable.class);

        //第三步,指定分区类
        job.setPartitionerClass(MyPartitioner.class);
        //第四, 五,六步
        //第七步:指定Reducer类和数据类型(K3和V3)
        job.setReducerClass(PartitionerReducer.class);
        job.setOutputValueClass(Text.class);
        job.setOutputValueClass(NullWritable.class);
        //设置ReduceTask的个数
        job.setNumReduceTasks(2);

        //第八步:指定输出类和输出路径
        job.setOutputFormatClass(TextOutputFormat.class);
        //TextOutputFormat.setOutputPath(job, new Path("hdfs://node01:8020/out/partition_out"));
        TextOutputFormat.setOutputPath(job, new Path("file:///D:\\out\\partition_out3"));

        //3:等待任务结束
        boolean bl = job.waitForCompletion(true);

        return bl?0:1;
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();
        //启动job任务
        int run = ToolRunner.run(configuration, new JobMain(), args);
        System.exit(run);
    }
}

查看运行结果(本地运行)

 

 

 

 可以清楚的看到分区成功!!!

posted @ 2020-08-29 15:44  17_Xtreme  阅读(184)  评论(0编辑  收藏  举报