2014-10-27 34 views
1

我有产生制表符分隔的文件,即在同一个文件运转三个MapReduce作业。第一个值是关键。这三个MR作业的每个输出都是这种情况。合并制表符分隔文件通过关键

我想现在要做的,就是用的MapReduce来者皆“十字绣”这些文件一起。最好的Mapper输出和Reducer输入是什么?我尝试使用ArrayWritable,但由于shuffle,对于某些记录,来自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 

我应该如何设置我的映射和消脂,去解决这个问题?

+1

也许二次排序和值(每个MR作业一个)手动前缀是你在找什么...看看(http://hadoop.apache.org/docs/r2.2.0/api /org/apache/hadoop/mapreduce/Reducer.html) – vefthym 2014-10-27 16:22:40

+1

@vefthym感谢您的提示。我会仔细看看的!如果我能管理一些东西,我会让你知道的。 – tolgap 2014-10-27 16:56:37

回答

1

有可能与所发射的价值简单的标签,因为只有三种类型的文件都参与其中。在地图中提取分割的路径,确定它的位置并为该值添加合适的前缀。为了清楚,说的输出在3个目录:

  1. 路径1/mr_out_1
  2. 路径2/mr_out_2
  3. 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); 

如果您将所有文件放在同一个目录中,请使用该文件名称而不是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对象创建开销。

+0

这是一个很好的建议,实施它非常简单。谢谢@blackSmith – tolgap 2014-10-31 12:19:45

相关问题