`

【Hadoop】利用MultipleOutputs,MultiOutputFormat实现以不同格式输出到多个文件

 
阅读更多

  这是小D 第一篇博客,有什么错误还请各位指正。

  

  小D 也是刚接触Hadoop ,因为在淘宝实习,有很多算法要在分布式环境下实现,所以这几天一直在看Hadoop,边用边学。

最近实现的一个算法需要reduce输出很多参数,每个参数的格式不一样,而且要做为下一次mapreduce的输入,大家都知道Hadoop的分布式操作系统HFS是以目录为节点读取文件的,每个reduce输出一个分片,所以必须把要输出的文件根据类型的不同输出到不同的目录中去。因为淘宝还在用 Hadoop 0.19的API ,所以没办法直接用MultipleOutputs 的write方法实现。

复制代码
write

public void write(KEYOUT key,
                  VALUEOUT value,
                  String baseOutputPath)
           throws IOException,
                  InterruptedException
Write key value to an output file name. Gets the record writer from job's output format. Job's output format should be a FileOutputFormat.
Parameters:
key - the key
value - the value
baseOutputPath - base-output path to write the record to. Note: Framework will generate unique filename for the baseOutputPath
Throws:
IOException
InterruptedException
复制代码

MultipleOutputs 没有类似”String baseOutputPath“ 属性。在0.19的API中MultipleOutputs只可以为不同类型的文件加上不同的前缀。比如先在main 函数指定

MultipleOutputs.addNamedOutput(datafliter, "rating", TextOutputFormat.class, Text.class, Text.class);
MultipleOutputs.addNamedOutput(datafliter, "bu", TextOutputFormat.class, Text.class, Text.class);

然后在reduce里实例化MultipleOutputs

复制代码
private MultipleOutputs mos ;

...

public void configure(JobConf conf) {
        mos = new MultipleOutputs(conf);
...
}
public void close() throws IOException {  
        mos.close();  
 } 


public void reduce(Text key, Iterator<Text> values,
            OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
....

  OutputCollector<Text, Text> rateoutput =mos.getCollector("rating", reporter);
        rateoutput.collect(new Text(key), new Text(sb.toString()));
  OutputCollector<Text, Text> rateoutput =mos.getCollector("bu", reporter);
        rateoutput.collect(new Text(key), new Text(sb.toString()));
}
复制代码

这样可以实现多个输出,在文件前加上相应的前缀。

但是这样做很多不同格式的文件还是会在一个output目录下,苦思冥想了半天,查各种资料,问周围同事,终于发现MapRedeuce 框架了还有一个货是专门干这个的 那就是MultipleOutputFormat , 它有两个子类MultipleTextOutputFormat 和MultipleSequenceOutputFormat 对应两种输出格式。但是想用这货还挺麻烦,要写一个子类继承他,重写父类的方法。

以我写的MultiOutputFormatByFileName 为例。这个类还可以定制key ,value 键值对的规则,这里我们不讨论这个,我们用到的是这两个方法

protected String generateLeafFileName(String name)
protected String generateFileNameForKeyValue(Text key, Text value, String name) 

第一个是根据原文件名生成一个新文件名,注意这里的新文件名可以包含目录,也就是可以写成 XX/XX/XX.dat,这样就可以生成新的目录。

第二个是根据文件中的键值对来生成文件名。也可以生成目录。

复制代码
package org.taobao.edp.tcif.titleExtract.util;

import java.io.File;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat;

public class MultiOutputFormatByFileName extends MultipleTextOutputFormat<Text, Text> {
    
    
    
    @Override
    protected String generateLeafFileName(String name) {
        // TODO Auto-generated method stub
        System.out.println(name);
        String[] names = name.split("-");
        
        return names[0]+File.separator+name;
    }
    
    @Override
    protected String generateFileNameForKeyValue(Text key, Text value,
            String name) {
        // TODO Auto-generated method stub
        return super.generateFileNameForKeyValue(key, value, name);
    }
    
}
复制代码

OK 我们重写第一个方法,之前我们通过MultipleOutput 生成了带前缀的文件名,现在我们把这个前缀提取出来作为目录名,代码如上。

然后我们修改 main

MultipleOutputs.addNamedOutput(init,"q", MultiOutputFormatByFileName.class , Text.class, Text.class);
MultipleOutputs.addNamedOutput(init,"x", MultiOutputFormatByFileName.class, Text.class, Text.class);
MultipleOutputs.addNamedOutput(init,"bi", MultiOutputFormatByFileName.class, Text.class, Text.class);
MultipleOutputs.addNamedOutput(init,"bu", MultiOutputFormatByFileName.class, Text.class, Text.class);     

用自己的MultiOutputFormatByFileName 替换框架的TextOutputFormat

这样就可以实现多目录输出喽!

真心希望公司的分布式平台能支持Hadoop 0.21的API , 一个简单的需求折腾了半天。

分享到:
评论

相关推荐

    Hadoop MultipleOutputs输出到多个文件中的实现方法

    主要介绍了 Hadoop MultipleOutputs输出到多个文件中的实现方法的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下

    winutils多个Hadoop版本

    winutils.exe是在window系统上安装hadoop时所需要的winutils文件,内附多个版本,支持 hadoop-2.6.3 hadoop-2.6.4 hadoop-2.7.1 hadoop-2.8.0-RC3 hadoop-2.8.1 hadoop-2.8.3 hadoop-3.0.0 已通过本人对 Hadoop-...

    java WriteHDFS实现,hadoop应用

    java WriteHDFS实现,hadoop应用java WriteHDFS实现,hadoop应用java WriteHDFS实现,hadoop应用java WriteHDFS实现,hadoop应用java WriteHDFS实现,hadoop应用java WriteHDFS实现,hadoop应用java WriteHDFS实现,...

    hadoop的dll文件 hadoop.zip

    hadoop的dll文件 hadoop.zip

    基于Hadoop实现的文件存储系统.zip

    基于Hadoop实现的文件存储系统 技术点redis:利用redisson来对上传文件进行布隆过滤(已上传的文件无需再次上传);进行session会话管理;HDFSAPI操作(项目功能):创建文件夹,上传文件,下载文件,删除文件,查找...

    基于hadoop用并行递归实现排列组合运算

    数字排列组合是个经典的算法问题,它很通俗易懂,适合不懂业务的人...这种算法常用递归或迭代来实现,单当M=14时,中间结果数量已经过亿,再大的话很容易超过单台机器的处理能力,所以我用hadoop来实现多机分别处理。

    Hadoop分布式文件系统的模型分析

    Hadoop分布式文件系统的模型分析,Hadoop 分布式文件系统是遵循Google 文件系统原理进行开发和实现的,受到了业界极大关注,并 已被广泛应用。 鉴于当前缺乏从系统设计理论的角度对其开展的相关研究,本文从 Hadoop ...

    HadoopHA集群配置文件

    Hadoop HA 集群搭建所需要的配置文件:core-site,hdfs-site,mapred-site,yarn-site四个xml文件和一个slaves文件

    hadoop/etc/hadoop/6个文件

    hadoop/etc/hadoop/6个文件 core-site.xml hadoop-env.sh hdfs-site.xml mapred-site.xml yarn-env.sh yarn-site.xml

    hadoop的默认配置文件

    hadoop的默认配置文件,下载记得关注我哦

    基于hadoop+hbase+springboot实现的分布式网盘系统,适合本科毕业设计

    基于hadoop+hbase+springboot实现的分布式网盘系统,适合本科毕业设计 资源包含的整个demo在Hadoop,和Hbase环境搭建好了,可以启动起来。 技术选型 1.Hadoop 2.Hbase 3.SpringBoot ...... 系统实现的功能 1.用户...

    基于Hadoop实现的数据云盘系统项目源码资料大全.zip

    基于Hadoop实现的数据云盘系统项目源码资料大全.zip基于Hadoop实现的数据云盘系统,实现不同用户有不同的存储空间,不同的用户身份有不同的权限操作等功能软件设计思路 1、用户登录模块设计 输入图片说明 2、检索...

    Hadoop mapreduce 实现KMeans

    Hadoop mapreduce 实现KMeans,可用

    Hadoop的MapReduce中多文件输出.pdf

    Hadoop的MapReduce中多文件输出.pdf

    hadoop2.7.3 hadoop.dll

    在windows环境下开发hadoop时,需要配置HADOOP_HOME环境变量,变量值D:\hadoop-common-2.7.3-bin-master,并在Path...解决方案:下载本资源解压将hadoop.dll和winutils.exe文件复制到hadoop2.7.3的bin目录下即可解决。

    Hadoop下载 hadoop-3.3.3.tar.gz

    Hadoop实现了一个分布式文件系统( Distributed File System),其中一个组件是HDFS(Hadoop Distributed File System)。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量...

    Hadoop mapreduce实现wordcount

    Hadoop 用mapreduce实现Wordcount实例,绝对能用

    利用ansible 自动 安装Hadoop 集群

    利用ansible 自动 安装Hadoop 集群

    基于Hadoop的Kmeans算法实现

    基于Hadoop的Kmeans算法实现:Kmeans算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标。即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的...

Global site tag (gtag.js) - Google Analytics