在我的 MapReduce 程序的 Reduce 阶段,我执行的唯一操作是连接提供的 Iterator 中的每个值,如下所示:
public void reduce(Text key, Iterator<text> values,
OutputCollector<Text, Text> output, Reporter reporter) {
Text next;
Text outKey = new Text()
Text outVal = new Text();
StringBuilder sb = new StringBuilder();
while(values.hasNext()) {
next = values.next();
sb.append(next.toString());
if (values.hasNext())
sb.append(',');
}
outKey.set(key.toString());
outVal.set(sb.toSTring());
output.collect(outKey,outVal);
}
我的问题是一些减少输出值是大行文本;如此之大,以至于即使初始大小非常大,字符串缓冲区也必须将其大小增加(加倍)数倍以容纳迭代器的所有上下文,从而导致内存问题。
在传统的 Java 应用程序中,这表明缓冲写入文件将是写入输出的首选方法。如何在 Hadoop 中处理超大的输出键值对?我应该将结果直接流式传输到 HDFS 上的文件(每个 reduce 调用一个文件)吗?除了 output.collect 方法之外,有没有办法缓冲输出?
注意:我已经尽可能地增加了我的内存/堆大小。此外,一些消息来源表明,增加 reducer 的数量可以帮助解决内存/堆问题,但这里的问题已直接追溯到 SringBuilder 在扩展其容量时的使用。
谢谢