前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MapReduce之自定义outputFormat

MapReduce之自定义outputFormat

作者头像
大数据梦想家
发布2021-01-22 16:54:32
3010
发布2021-01-22 16:54:32
举报

现在有一些订单的评论数据,需求: 将订单的好评与差评进行区分开来,将最终的数据分开到不同的文件夹下面去,其中数据第九个字段表示好评,中评,差评。0:好评,1:中评,2:差评。 根据我们之前学习的内容,大家可能第一时间想到的是自定义分区(不清楚的小伙伴们可以前往《MapReduce的自定义分区与ReduceTask数量》),但自定义分区后的程序运行的结果是数据保存在了同一个目录下的不同文件中。

而本题的关键点是要在一个mapreduce程序中根据数据的不同输出两类结果到不同目录,这类灵活的输出需求我们可以通过自定义outputformat来实现! 先让我们来看下需要实现的点有哪些?

1、在mapreduce中访问外部资源 2、自定义outputformat,改写其中的recordwriter,改写具体输出数据的方法write()

接下来我们开始上手代码!

第一步:自定义一个outputformat

代码语言:javascript
复制
public class Custom_OutputFormat extends FileOutputFormat<Text, NullWritable> {



    @Override
    public RecordWriter<Text, NullWritable> getRecordWriter(TaskAttemptContext context) throws IOException, InterruptedException {


        Configuration configuration = context.getConfiguration();

        FileSystem fileSystem = FileSystem.get(configuration);

        //两个输出路径
        FSDataOutputStream fsDataOutputStream1 = fileSystem.create(new Path("E:\\2019大数据课程\\DeBug\\测试结果\\outputformat1\\1.txt"));

        FSDataOutputStream fsDataOutputStream2 = fileSystem.create(new Path("E:\\2019大数据课程\\DeBug\\测试结果\\outputformat1\\2.txt"));

        Custom_RecordWriter custom_recordWriter = new Custom_RecordWriter(fsDataOutputStream1, fsDataOutputStream2);




        return custom_recordWriter;

    }
}

第二步:自定义一个RecordWriter

代码语言:javascript
复制
public class Custom_RecordWriter extends RecordWriter<Text, NullWritable> {


    FSDataOutputStream out1 = null;

    FSDataOutputStream out2 = null;


    @Override
    public String toString() {
        return "Custom_RecordWriter{" +
                "out1=" + out1 +
                ", out2=" + out2 +
                '}';
    }

    public FSDataOutputStream getOut1() {
        return out1;
    }

    public void setOut1(FSDataOutputStream out1) {
        this.out1 = out1;
    }

    public FSDataOutputStream getOut2() {
        return out2;
    }

    public void setOut2(FSDataOutputStream out2) {
        this.out2 = out2;
    }

    public Custom_RecordWriter() {
    }

    public Custom_RecordWriter(FSDataOutputStream out1, FSDataOutputStream out2) {
        this.out1 = out1;
        this.out2 = out2;
    }



    /**
     * 写入数据的方法
     * @param key   要写入的key值
     * @param value   要写入的value
     * @throws IOException
     * @throws InterruptedException
     */

    @Override
    public void write(Text key, NullWritable value) throws IOException, InterruptedException {

               if (key.toString().split("\t")[9].equals("0")){
                   //好评
                   out1.write(key.toString().getBytes());


               }else{


                   //中评和差评
                   out2.write(key.toString().getBytes());
                   out2.write("\r\n".getBytes());

               }



    }

    //  关闭
    @Override
    public void close(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {

        if (out1!=null){
            out1.close();
        }

        if (out2!=null){
            out2.close();
        }



    }
}

第三步:Map

代码语言:javascript
复制
public class Custom_Mapper extends Mapper<LongWritable, Text,Text, NullWritable> {



    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {


        context.write(value,NullWritable.get());


    }

开发mapreduce处理流程

代码语言:javascript
复制
public class Custom_Driver {


    public static void main(String[] args) throws Exception {


        Job job = Job.getInstance(new Configuration(), "Customer_Driver");

        job.setJarByClass(Custom_Driver.class);

        //设置输入
        job.setInputFormatClass(TextInputFormat.class);

        TextInputFormat.addInputPath(job,new Path("E:\\2019大数据课程\\DeBug\\测试\\ordercomment.csv"));

        job.setMapperClass(Custom_Mapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(NullWritable.class);

        job.setOutputFormatClass(Custom_OutputFormat.class);

        // 这里path的路径可以任意设置,因为我们在自定义outPutFormat中已经将输出路径确定
        Custom_OutputFormat.setOutputPath(job,new Path("E:\\2019大数据课程\\DeBug\\测试结果\\outputformat1"));

        boolean b = job.waitForCompletion(true);

        System.out.println(b?0:1);


    }
}

将代码写完后,我们开始测试程序!

目标文件:ordercomment.csv

在这里插入图片描述
在这里插入图片描述

程序运行完后,我们进入到outputformat1目录下,看到程序将我们想要的不同的结果放在了两个独立的文件中!

在这里插入图片描述
在这里插入图片描述

分别打开文件查看内容

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到了这里说明我们的自定义outputFormat算是成功了。那本期的分享到这里也就该结束了,小伙伴们有什么疑惑或好的建议可以在评论区留言或者私信小菌都是可以的。小菌有抽时间一一回复大家,另外,受益的小伙伴们记得关注小菌(^U^)ノ~YO。是你们默默的支持鼓舞着小菌不辞辛苦的为大家每天更新新鲜的博客!之后小菌会更新更多好玩的内容,敬请期待!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一步:自定义一个outputformat
  • 第二步:自定义一个RecordWriter
  • 第三步:Map
  • 开发mapreduce处理流程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档