Редуктор выводит значение для двух разных ключей в одном файле

Привет, я написал задание mapreduce, которое обычно анализирует файл XML. Я могу разобрать файл XML и правильно сгенерировать всю пару значений ключа. У меня есть 6 разных ключей и соответствующие значения. Итак, я запускаю 6 разных редукторов параллельно.

Теперь проблема, с которой я столкнулся, заключается в том, что редуктор помещает две разные пары ключ-значение в один и тот же файл и оставшиеся 4 значения ключа в отдельные файлы. Короче говоря, из 6 файлов на выходе из редуктора я получаю 4 файла с парой значений с одним ключом и 1 файл с двумя парами ключ-значение и 1 файл без ничего.

Я попытался провести исследование в Google и на различных форумах, и пришел к выводу, что мне нужен разделитель для решения этой проблемы. Я новичок в Hadoop, поэтому может кто-нибудь пролить свет на эту проблему и помочь мне решить ее.

Я работаю над кластером псевдоузлов и использую Java в качестве языка программирования. Я не могу поделиться здесь кодом, но все же попытаюсь кратко описать проблему.

Дайте мне знать, что требуется дополнительная информация, и спасибо заранее.


person user1188611    schedule 24.04.2013    source источник
comment
Привет, мой ответ ниже помог тебе?   -  person SSaikia_JtheRocker    schedule 26.05.2013


Ответы (2)


Иметь только 6 ключей для 6 редьюсеров — не лучшее использование хаупа — хотя было бы неплохо, чтобы каждый из 6 переходил на отдельный редьюсер, это не гарантируется.

Ключи не могут быть разделены между редьюсерами, поэтому, если у вас будет менее 6 ключей, только подмножество ваших редукторов будет выполнять какую-либо работу. Вам следует подумать о том, чтобы переосмыслить назначение клавиш (и, возможно, соответствие входных файлов для Hadoop) и, возможно, использовать такую ​​систему, чтобы было достаточно ключей для равномерного распределения среди редукторов.

РЕДАКТИРОВАТЬ: я считаю, что вам может понадобиться MultipleOutputFormat, который имеет метод generateFileNameForKeyValue(key, value, name), что позволяет создавать файл для записи для каждого ключа, а не только один файл для Reducer.

person Quetzalcoatl    schedule 24.04.2013
comment
Да, пожалуйста, уточните. Я думаю, что вы неправильно интерпретировали вопрос. Я вывожу из картографа разные ключи уникальным образом, но я хочу, чтобы каждый ключ и соответствующие ему значения находились в отдельных файлах. Для этого у меня есть n количество редукторов. Но проблема в том, что редуктор выводит два разных ключа и соответствующие значения в одном файле. Если вы сможете ответить на свой ответ, помня об этой проблеме, это будет здорово. - person user1188611; 25.04.2013

Hadoop по умолчанию использует разделитель хэшей по умолчанию — нажмите здесь, что-то вроде

public class HashPartitioner<K2, V2> implements Partitioner<K2, V2> {

  public void configure(JobConf job) {}

  /** Use {@link Object#hashCode()} to partition. */
  public int getPartition(K2 key, V2 value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }

}

key.hashCode() & Integer.MAX_VALUE) % numReduceTasks вернет число от 0 до numReduceTasks, и в вашем случае диапазон будет от 0 до 5, поскольку numRuduceTask=6

Загвоздка именно в этой строке — два таких оператора могут вернуть вам одно и то же число. И в результате на один и тот же редуктор могли идти два разных ключа. Например,

("go".hashCode() & Integer.MAX_VALUE) % 6

вернет вам 4 и,

("hello".hashCode() & Integer.MAX_VALUE) % 6

также вернет вам 4.

Итак, что я бы посоветовал здесь, так это то, что если вы хотите быть уверены, что все ваши 6 ключей обрабатываются 6 различными редьюсерами, вам нужно создать свой собственный разделитель, чтобы получить то, что вы хотите.

Перейдите по этой ссылке, чтобы создать собственный разделитель, если у вас возникла путаница, и вы указали свой собственный разделитель примерно так, как показано ниже, с помощью класса Job.

job.setPartitioner(<YourPartionerHere.class>);

Надеюсь это поможет.

person SSaikia_JtheRocker    schedule 11.05.2013