我有一个小的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步骤,但似乎找不到有用的东西。
谢谢!
答案 0 :(得分:0)
reducer确实获得了所有这些数据,但是这些数据实际上是写入磁盘的,只有在迭代Iteratable值时才会被带入内存。事实上,该迭代返回的对象将被重用于每个值:在将对象交给您之前,只需替换字段和其他状态。
这意味着您必须显式复制值对象,以便同时在内存中包含所有值对象。
当我查看你的代码时,似乎你没有将项目对保存在内存中。你是直接写出项目对,所以你应该很好。