Hadoop MultipleOutPutFormat和联接查询

Hadoop MultipleOutPutFormat和联接查询,hadoop,Hadoop,我正在从事一项hadoop任务,该任务之前在一个目录中填充了几个文件,比如 第o部分 第一部分 第二部分 由于一个需求,我修改了这个任务,并使用multipleoutput来捕获更多的输出。现在目录结构看起来像 第0部分 第一部分 第二部分 产出-1 产出-2 产出-3 问题:以前很少有作业使用此目录进行映射端外部联接,但现在该作业只需使用部分-*文件进行联接,并放弃其余文件 我尝试将输入作为一个单独的目录 i、 e/part-1,/part-2,*/part-3 根据下面的表达式 jobCon

我正在从事一项hadoop任务,该任务之前在一个目录中填充了几个文件,比如

第o部分 第一部分 第二部分

由于一个需求,我修改了这个任务,并使用multipleoutput来捕获更多的输出。现在目录结构看起来像

第0部分 第一部分 第二部分 产出-1 产出-2 产出-3

问题:以前很少有作业使用此目录进行映射端外部联接,但现在该作业只需使用部分-*文件进行联接,并放弃其余文件

我尝试将输入作为一个单独的目录 i、 e/part-1,/part-2,*/part-3

根据下面的表达式 jobConf.set(“mapred.join.expr”,CompositeInputFormat.compose(外部, KeyValueTextInputFormat.class,路径[])

现在我的路径[]包含5个entires,ealier以前是3个,在某种程度上,开始的三个索引有/part-1、/part-2、*/part-3路径,其余两个与前面一样

我不确定我这样做是否正确,请建议我应该怎么做,以使此联接与以前在没有输出-*文件的情况下正常工作

它使用上述方法引发以下异常

java.io.IOException:子1的拆分基数不一致(12/6) org.apache.hadoop.mapred.join.Parser$CNode.getSplits(Parser.java:369) org.apache.hadoop.mapred.join.CompositeInputFormat.getSplits(CompositeInputFormat.java:117) org.apache.hadoop.mapred.JobClient.writeldsplits(JobClient.java:810) org.apache.hadoop.mapred.JobClient.submitJobInternal(JobClient.java:781) org.apache.hadoop.mapred.JobClient.submitJob(JobClient.java:730)

JobConf值如下所示

 jobConf.setMapperClass(MyMapper.class);
    jobConf.setReducerClass(MyReducer.class);

  String[] foldersToJoin = StringUtils.split(getInputString(), Constants.COMMA);
    Path[] pathsToJoin =  new Path[foldersToJoin.length];
    int i = 0;
    for(String folder : foldersToJoin){
        pathsToJoin[i++] = new Path(folder);
    }

 FileOutputFormat.setOutputPath(jobConf, new Path("/MyOutPUT"));

    jobConf.setInputFormat(CompositeInputFormat.class);
    jobConf.set("mapred.join.expr", CompositeInputFormat.compose(Constants.OUTER_JOIN_OP,
            KeyValueTextInputFormat.class, pathsToJoin));

    jobConf.setOutputFormat(TextOutputFormat.class);
    jobConf.setOutputKeyClass(Text.class);
    jobConf.setOutputValueClass(Text.class);

    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_A,
            TextOutputFormat.class, Text.class, Text.class);
    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_B,
            TextOutputFormat.class, Text.class, Text.class);
    MultipleOutputs.addNamedOutput(jobConf,CHANGE_SET_C,
            TextOutputFormat.class, Text.class, Text.class);
    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_D,
            TextOutputFormat.class, Text.class, Text.class);
我将文件夹中的所有文件作为一个“,”分隔字符串追加,下面是代码

  mapred.join.expr = CompositeInputFormat.compose(Constants.OUTER_JOIN_OP,
        KeyValueTextInputFormat.class, pathsToJoin)

   where pathsToJoin =  new Path[]{new Path["/home/hadoop/folder1/part-1"],
  new Path["/home/hadoop/folder1/part-2"],new Path["/home/hadoop/folder1/part-3"],
   new Path["/home/hadoop/folder2"],new Path["/home/hadoop/folder3"] }
因此,基本上我只尝试将folder1中的部分-*文件与folder2和folder3连接起来


任何文档,或任何指向此类场景的链接都会有很大帮助。

好的,我想我现在明白了

您已执行多个作业,这些作业已将其内容输出到文件夹:

job1 -> folder1
job2 -> folder2
job3 -> folder3
现在,您希望使用CompositeInputFormat合并每个文件夹中每个part-r-x的输出,并在单个映射器中进行处理

map0 - merged contents of folder1/part-r-0, folder2/part-r-0, folder3/part-r-0
map1 - merged contents of folder1/part-r-1, folder2/part-r-1, folder3/part-r-1
.. and so on ..
增加的复杂性是,一个或多个作业使用了multipleoutput,因此,与folder1中的part-r-x文件不同,您需要

job1 -> folder1/part-x and folder1/output-x
当您使用
复合输入格式时,会出现错误,因为folder1的文件比folder2和3的多

在这种情况下,我认为您需要修改
mapred.join.expr
值以使用一些glob:

// use glob for folder1, to only include the part-x files (ignoring the output-x files)
CompositeInputFormat.compose(Constants.OUTER_JOIN_OP, KeyValueTextInputFormat.class,
   new Path[] {
       new Path('folder1/part-*'),
       new Path('folder2/part-r-*'),
       new Path('folder3/part-r-*'),
   });

你能发布你的驱动程序代码吗(你调用JobConf.setXXX方法的地方)。我想在为CombineInputFormat定义输入文件时,您只需要设计一个更好的glob就可以了。添加了有问题的jobConf代码。您在哪里设置
pathsToJoin
数组的值?能否同时显示已解析的作业配置属性
“mapred.join.expr”
-谢谢!mapred.join.expr=CompositeInputFormat.compose(Constants.OUTER_join_OP,KeyValueTextInputFormat.class,pathsToJoin),其中pathsToJoin=new Path[]{new Path[“/home/hadoop/folder1/part-1”]、new Path[“/home/hadoop/folder1/part-3”]、new Path[“/home/hadoop/folder2”]、new Path[/home/hadoop/folder2”][“/home/hadoop/folder3”]}假设您已经阅读了Tom White的《hadoop权威指南》,那么您还想掌握什么呢?就像您必须进行的大多数实验一样,并从错误中吸取教训