На этапе сокращения моей программы MapReduce единственной операцией, которую я выполняю, является объединение каждого значения в предоставленном итераторе, как показано ниже:
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 (один файл на вызов сокращения)? Есть ли способ буферизовать вывод, кроме метода output.collect?
Примечание. Я уже максимально увеличил объем памяти/кучи. Кроме того, несколько источников указали, что увеличение количества редьюсеров может помочь с проблемами памяти/кучи, но здесь проблема напрямую связана с использованием SringBuilder, когда он расширяет свою емкость.
Спасибо