MapReduce多Job串联及Partitioner

数据:
Input:
name hwl chinese 100 math 100 english 55
name lh chinese 99 math 45 english 54
name zs chinese 52 math 95 english 51
name bb chinese 96 math 89 english 57
name lk chinese 71 math 60 english 50
name ll chinese 32 math 12 english 72
name dd chinese 63 math 74 english 13
Output:
chinese	zs:52;ll:32;dd:63;hwl:100;bb:96;lk:71;lh:99;
english	hwl:55;zs:51;bb:57;ll:72;dd:13;lh:54;lk:50;
math	hwl:100;lh:45;zs:95;lk:60;ll:12;dd:74;bb:89;
代码:
package MapReducer05;

import com.google.inject.internal.util.$StackTraceElements;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.jobcontrol.ControlledJob;
import org.apache.hadoop.mapreduce.lib.jobcontrol.JobControl;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.log4j.BasicConfigurator;

import java.io.IOException;

public class ScoreMR {
    public static class MyMapper01 extends Mapper<LongWritable, Text, Text, Text>{
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String[] str = value.toString().split(" ");
            context.write(new Text(str[2]), new Text(str[1]+":"+str[3]));
            context.write(new Text(str[4]), new Text(str[1]+":"+str[5]));
            context.write(new Text(str[6]), new Text(str[1]+":"+str[7]));
        }
    }
    public static class MyMapper02 extends Mapper<LongWritable, Text, Text, Text>{
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            /*InputSplit is = context.getInputSplit();
            FileSplit fsp = (FileSplit) is;
            String fname = fsp.getPath().getName();*/
            String[] str = value.toString().split("\t");
            context.write(new Text(str[0]), new Text(str[1]));
        }
    }
    public static class MyReducer02 extends Reducer<Text, Text, Text, Text>{
        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            String res = "";
            for(Text t : values){
                res += t.toString()+";";
            }
            context.write(key, new Text(res));
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        System.setProperty("hadoop.home.dir", "F:\\hadoop-2.6.4");
        BasicConfigurator.configure();
        Configuration conf1 = new Configuration();
        Configuration conf2 = new Configuration();

        Job job1 = Job.getInstance(conf1, "mr1");
        job1.setJarByClass(ScoreMR.class);

        job1.setMapperClass(MyMapper01.class);
        job1.setMapOutputKeyClass(Text.class);
        job1.setMapOutputValueClass(Text.class);
        //分区
        job1.setPartitionerClass(MyPartitioner.class);
        job1.setNumReduceTasks(3);

        FileInputFormat.addInputPath(job1, new Path("C:\\Users\\Chen\\Desktop\\input\\00"));
        FileOutputFormat.setOutputPath(job1, new Path("C:\\Users\\Chen\\Desktop\\30"));

        Job job2 = Job.getInstance(conf2, "mr2");
        job2.setJarByClass(ScoreMR.class);

        job2.setMapperClass(MyMapper02.class);
        job2.setMapOutputKeyClass(Text.class);
        job2.setMapOutputValueClass(Text.class);

        job2.setReducerClass(MyReducer02.class);
        job2.setOutputKeyClass(Text.class);
        job2.setOutputValueClass(Text.class);

        FileInputFormat.setInputPaths(job2, new Path("C:\\Users\\Chen\\Desktop\\30"));
        FileOutputFormat.setOutputPath(job2, new Path("C:\\Users\\Chen\\Desktop\\31"));

        JobControl jobControl = new JobControl("jobControl");
        ControlledJob cj1 = new ControlledJob(job1.getConfiguration());
        ControlledJob cj2 = new ControlledJob(job2.getConfiguration());

        cj2.addDependingJob(cj1);
        jobControl.addJob(cj1);
        jobControl.addJob(cj2);

        Thread thread = new Thread(jobControl);
        thread.start();

        while (!jobControl.allFinished()){
            thread.sleep(1000);
        }
        jobControl.stop();
        System.exit(0);
        //System.exit(job2.waitForCompletion(true) ? 0 : 1);
    }
}
class MyPartitioner extends Partitioner<Text, Text> {
    @Override
    public int getPartition(Text text, Text text2, int numPartitions) {
        String str = text.toString();
        if(str.startsWith("chinese")){
            return 0%numPartitions;//0
        } else if(str.startsWith("math")){
            return 1%numPartitions;
        } else{
            return 2%numPartitions;
        }
    }
}

中间文件:
part-r-00000:
chinese	lh:99
chinese	lk:71
chinese	bb:96
chinese	hwl:100
chinese	dd:63
chinese	ll:32
chinese	zs:52
part-r-00001:
math	bb:89
math	dd:74
math	ll:12
math	lk:60
math	zs:95
math	lh:45
math	hwl:100

part-r-00002:
english	lk:50
english	lh:54
english	dd:13
english	ll:72
english	bb:57
english	zs:51
english	hwl:55
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MapReduce使用Partitioner的主要目的是将Map任务的输出结果进行分区,确保具有相同键的键值对被发送到同一个Reduce任务进行处理。使用Partitioner有以下几个原因: 1. 数据局部性:通过将具有相同键的键值对发送到同一个Reduce任务,可以提高数据的局部性。在MapReduce中,数据通常存储在分布式文件系统中,Reduce任务需要从不同的节点获取数据进行处理。如果相同键的数据被分散在不同的节点上,Reduce任务需要跨网络获取数据,增加了网络传输开销。而使用Partitioner可以尽量将相同键的数据放置在同一台机器上,减少数据的跨网络传输,提高作业的执行效率。 2. 平衡负载:Partitioner可以帮助实现Reduce任务之间的负载均衡。通过使用哈希函数对键进行哈希,并将哈希值映射到不同的分区,可以尽量保证每个分区中包含大致相等数量的键值对。这样可以避免某些Reduce任务负载过重,而其他任务负载较轻的情况,提高整个作业的并行处理能力。 3. 自定义分区逻辑:Partitioner可以根据用户的需求进行自定义。默认情况下,MapReduce框架使用哈希函数和取模运算来决定分区。但是,用户可以通过实现自己的Partitioner类,根据自己的业务逻辑进行分区。例如,根据数据的某个属性进行分区,或者根据其他规则进行分区,以满足特定的需求。 总而言之,使用Partitioner可以提高作业的执行效率,减少数据的跨网络传输开销,实现负载均衡,并且允许用户根据自己的需求进行自定义分区逻辑。这是为什么MapReduce要使用Partitioner的主要原因之一。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值