MapReduceプログラムのReduceフェーズでは、以下のように、提供されたイテレーターの各値を連結するだけの操作を実行します。
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);
}
私の問題は、reduce出力値の一部が巨大なテキスト行であるということです。非常に大きいため、初期サイズが非常に大きい場合でも、イテレータのすべてのコンテキストに対応するために、文字列バッファのサイズを数倍に増やす(2倍にする)必要があり、メモリの問題が発生します。
従来のJavaアプリケーションでは、これは、ファイルへのバッファ書き込みが出力の書き込みに適した方法であることを示しています。Hadoopで非常に大きな出力キーと値のペアをどのように処理しますか?結果をHDFS上のファイルに直接ストリーミングする必要がありますか(reduce呼び出しごとに1つのファイル)?output.collectメソッド以外に、出力をバッファリングする方法はありますか?
注:メモリ/ヒープサイズを可能な限り最大限に増やしました。また、いくつかの情報源は、レデューサーの数を増やすとメモリ/ヒープの問題に役立つ可能性があることを示していますが、ここでの問題は、容量を拡張している間のSringBuilderの使用に直接起因しています。
ありがとう