MapReduce的分区 (Partition)

分区的概念

      在MapReduce中,数据进行map转换后,默认根据map后数据的key值进行散列派发,同一个分区的数据发送到同一个Reduce中去处理。但实际中,这种方式不是高效的,并且有时并不能满足我们的需求。所以我们需要自定义分区方式,根据自己的需求,选择记录的reducer。进行自定义分区时,我们需要继承Partitioner类,重写get方法,实现自定义分区。

分区的实现

        首先。我们来看看Partitioner类。Partitioner类需要传入两个参数,分别是进行map操作后的key值和value值。在get方法中传入三个参数map操作后的key值、value值及reduceTask的个数。在自定义分区时,若不设置默认是1个。

MapReduce的分区 (Partition)_第1张图片
        可以仿照Patitioner类的实现类HashPartitioner编写自己的分区类。
MapReduce的分区 (Partition)_第2张图片

举例:对表中第六个字段小于15的和大于等于15的数据进行分区。

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

public class PartitionerOwn extends Partitioner {
    /**
     * 自定义如何分区
     * @param text  key2那行数据
     * @param nullWritable  v2
     * @param i   reduceTask数量
     * @return
     */
    @Override
    public int getPartition(Text text, NullWritable nullWritable, int i) {
        String[] split = text.toString().split("\t");
        String gameResult =  split[5];
        if(null != gameResult  && "" != gameResult ){
           //如果开奖结果大于15,大于15的数据到0号分区
           if(Integer.parseInt(gameResult)>15){
               return 0;
           }else{
               //如果开奖结果小于等于15,数据到1号分区
              return 1;
           }
       }
       return 0;
    }
}

在run方法中添加 一行代码:

    //第三步:设置分区类,使用自定义分区类进行分区
    job.setPartitionerClass(PartitionerOwn.class);
    job.setNumReduceTasks(2);

你可能感兴趣的:(MapReduce分区)