在hadoop中创建所有值对列表

时间:2017-11-10 19:10:37

标签: java hadoop mapreduce

我有一个小的map-reduce程序我正在为hadoop编写,该程序的一个元素是创建所有的列表对。例如,如果程序的输入是:

item1 tag1  
item2 tag1  
item3 tag2  
item4 tag1  
item5 tag2  

我的地图功能会创建一个<tag, item>对,因此reducer会收到<tag, List<item>>作为输入。我的目标是减速器的输出为:

item1-item2 tag1  
item1-item4 tag1  
item2-item4 tag1  
item3-item5 tag2

基本上,对于每个值列表,创建所有可能的对,并使每对成为一个键 我找到了一个有效的解决方案,但它依赖于将列表复制到内存中并迭代它。这可能是一个问题,因为我的数据集可能非常大:

public void reduce(Text key, Iterable<Text> values, Context context) 
                         throws IOException, InterruptedException {

    List<String> list = new ArrayList<String>();
    for (Text t : values) {
        list.add(t.toString());
    }
    for (int i=0; i<list.size()-1; i++) {
        for (int j=i+1; j<list.size(); j++) {
            out.set(list.get(i) + "-" + list.get(j))
            context.write(out, one);
        }
    }
}

在hadoop中有替代或更有效的方式吗?
我不想将每个列表复制到内存中。

我一直试图想出一些创意,比如使用另一个map-reduce步骤,但似乎找不到有用的东西。

谢谢!

1 个答案:

答案 0 :(得分:0)

reducer确实获得了所有这些数据,但是这些数据实际上是写入磁盘的,只有在迭代Iteratable值时才会被带入内存。事实上,该迭代返回的对象将被重用于每个值:在将对象交给您之前,只需替换字段和其他状态。

这意味着您必须显式复制值对象,以便同时在内存中包含所有值对象。

当我查看你的代码时,似乎你没有将项目对保存在内存中。你是直接写出项目对,所以你应该很好。