MapReduce的分区操作

原始的数据如图所示:
在这里插入图片描述
我要按照第六个字段的大小进行分区,大于15的分成一区,小于15的分成一区。
实现的流程如下:
首先,需要四个类,自定义的partition类,Mapper类,Reduce类和负责任务整体调度的partitionMain类。
各个类的代码如下:
自定义partitioner类
里面设置了我们的分区的逻辑,即以15为分割线将数据进行分区。

package com.legendlee.partition;

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

public class partitionOwn extends Partitioner<Text,NullWritable> {
    /**
     * 这个方法就是我们自己来定义如何分区
     * @param text 行文本内容
     * @param nullWritable v2
     * @param numPartitions reduceTask的数量
     * @return
     */
    @Override
    public int getPartition(Text text, NullWritable nullWritable, int numPartitions) {
        //将文本的内容进行切割,返回的是字符串的数组
        String[] split = text.toString().split("\t");
        //取第六行的数据然后进行分区
        String result = split[5];
        if(null!= result&&result!=""){
            if(Integer.parseInt(result)>15){
                return 0;
            }else {
                return 1;
            }
        }
         return 0;
    }
}

Mapper类

package com.legendlee.partition;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * mapper<k1,v1,k2,v2>
 *     k1:行偏移量
 *     v1:行文本的内容
 *     k2:行文本的内容
 *     v2:NullWritable
 */
public class partitionMapper extends Mapper<LongWritable,Text,Text,NullWritable>{

    //直接把k2的内容写出去即可
    /**
     *mapper的作用就是将文本的内容写出去
     * @param key 行偏移量
     * @param value 行文本的内容
     * @param context 上下文对象
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        context.write(value,NullWritable.get());
    }
}

首先需要思考两个问题,mapper接收和输出的都是什么数据?mapper要实现的功能逻辑是什么?
接收的数据:
k1:行偏移量
v1:行文本的内容
输出的数据:
k2:行文本的内容
v2:可以直接省略NullWritable
实现的功能逻辑:
因为我们在自定义partitioner中实现了分区的逻辑,所以在mapper阶段,只需将数据输出给reduce即可。
Reduce类

package com.legendlee.partition;

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

import java.io.IOException;

public class partitionReducer extends Reducer<Text,NullWritable,Text,NullWritable> {
    /**
     * reduce阶段不做任何处理  直接把行文本输出即可
     * @param key
     * @param values
     * @param context
     * @throws IOException
     * @throws InterruptedException
     */
//    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        context.write(key,NullWritable.get());
    }
}

同理分析
partionMain类

package com.legendlee.partition;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.lib.HashPartitioner;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

//固定写法
public class partionMain extends Configured implements Tool {
    /**
     * run方法实现整个任务的调度
     * @param args
     * @return
     * @throws Exception
     */
    @Override
    public int run(String[] args) throws Exception {
        //创建一个job对象
        Job job = Job.getInstance(new Configuration(), "legendlee");
        //设置打包类型
        job.setJarByClass(partionMain.class);
        //第一步:读取文件,解析成key,value对
        job.setInputFormatClass(TextInputFormat.class);
        //添加要读取的文件的路径,path的路径作为参数进行动态的传递
        TextInputFormat.addInputPath(job,new Path(args[0]));
        //第二步:自定义map的逻辑
        job.setMapperClass(partitionMapper.class);
        //设置map输出的类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(NullWritable.class);
        //第三步:设置分区类
        job.setPartitionerClass(partitionOwn.class);
        //第四步到第六步省略
        //第七步:自定义reduce逻辑
        job.setReducerClass(partitionReducer.class);
        //设置reduce的输出的类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);
        //设置reduce的个数
        job.setNumReduceTasks(2);
        //第八步:设置输出类
        job.setOutputFormatClass(TextOutputFormat.class);
        //输出路径不写死   通过参数传递
        TextOutputFormat.setOutputPath(job,new Path(args[1]));
        boolean b = job.waitForCompletion(true);
        return b?0:1;
    }

    public static void main(String[] args) throws Exception {
        //main方法主要通过ToolRunne.run将程序跑起来
        int run = ToolRunner.run(new Configuration(), new partionMain(), args);
        System.exit(run);

    }
}

然后将工程打成jar包
将jar包放在Linux服务器
然后运行得到的结果如下:
在这里插入图片描述
因为设置了两个reduceTask,最后生成了两个结果输出文件
在这里插入图片描述
打开如图所示:
这个都是小于15的数据区
在这里插入图片描述
大于15的数据区:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值