我有三个MapReduce作业,它们产生制表符分隔的文件,并对相同的文件进行操作。第一个值是密钥。这三个MR作业的每个输出都是这种情况。

我现在想做的是使用MapReduce通过密钥将这些文件“缝合”在一起。最好的Mapper输出和Reducer输入是什么?我尝试使用ArrayWritable,但是由于混洗,对于某些记录,来自1文件的ArrayWritable位于第三位置,而不是第二位置。

我要这个:

Key \t Values-from-first-MR-job \t Values-from-second-MR-job \t Values-from-third-MR-job

对于所有记录,这应该是相同的。但是,正如我所说,由于混洗,有时会发生一些记录:
Key \t Values-from-third-MR-job \t Values-from-first-MR-job \t Values-from-second-MR-job

我应该如何设置Mapper和Reducer来解决此问题?

最佳答案

由于仅涉及三种类型的文件,因此可以通过简单标记输出值来实现。在 map 中,提取分割的路径,确定其位置,然后在值上添加合适的前缀。为了清楚起见,假设输出位于3个目录中:

  • path1 / mr_out_1
  • path2 / mr_out_2
  • path3 / mr_out_3

  • 对所有这些路径使用TextInputForamt,在map中,您将执行以下操作:
    String[] keyVal = value.spilt("\t",2);
    
    Path filePath = ((FileSplit) context.getInputSplit()).getPath();
    String dirName = filePath.getParent().getName().toString();
    
    Text outValue = new Text();
    if(dirName.equals("mr_out_1")){
        outValue.set("1_" + keyVal[1]);
    } else if(dirName.equals("mr_out_2")){
        outValue.set("2_" + keyVal[1]);
    } else {
        outValue.set("3_" + keyVal[1]);
    }
    
    context.write(new Text(keyVal[0]), outVal);
    

    如果所有文件都在同一目录中,请使用fileName而不是dirName。然后根据名称识别标志(正则表达式匹配可能合适):
    String fileName = filePath.getName().toString();
    if(fileName.matches("regex")){ ... }
    

    reduce中,只需将传入值放入列表并进行排序。休息很简单。
    List<String> list = new ArrayList<String>(3);
    for(Text v : values){
        list.add(v.toString());
    }
    Collections.sort(list);
    
    StringBuilder builder = new StringBuilder();
    for(String s : list){
        builder.append(s.substring(2)+"\t");
    }
    
    context.write(key, new Text(builder.toString().trim()));
    

    我认为这将达到目的。请记住,如果文件超过9个(由于字母顺序),则Collection.sort策略将失败。然后,您可以分别提取标签,将其转换为Integer并使用TreeMap<tag, actualString>进行排序。

    注意:以上所有代码段均使用新的API。我没有使用IDE编写这些代码,因此可能几乎没有语法错误。再一次,我没有遵循适当的书面约定。假设map的outKey可以是一个类成员,并且使用outKey.set(keyVal[0])可以消除Text对象创建的开销。

    关于java - 按键合并制表符分隔的文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26587957/

    10-11 22:48
    查看更多