Я работаю над программой MapReduce, в которой мне нужно вставить объекты в базу данных. Из-за некоторой проблемы с производительностью вставка объектов в базу данных должна выполняться в объединителе. Моя программа не имеет редуктора, поэтому есть только компаньон и комбайнер. Поскольку механизм Hadoop может не выполнять комбайнер (компилятор не является обязательным), как я могу обеспечить его выполнение для запуска объединителя?Как обеспечить выполнение программы mapreduce для выполнения объединения?
ответ
Рамка MapReduce не поддерживает поддерживаемый способ принудительного выполнения объединителя. Объединитель можно назвать 0, 1 или несколько раз. Рамки могут принимать собственные решения по этому поводу.
Текущая реализация решает запустить объединитель на основе разливов на диск, возникающих при выполнении задачи карты. Документация Apache Hadoop для mapred-default.xml документирует несколько свойств конфигурации, которые могут влиять на активность разлива.
<property>
<name>mapreduce.map.sort.spill.percent</name>
<value>0.80</value>
<description>The soft limit in the serialization buffer. Once reached, a
thread will begin to spill the contents to disk in the background. Note that
collection will not block if this threshold is exceeded while a spill is
already in progress, so spills may be larger than this threshold when it is
set to less than .5</description>
</property>
<property>
<name>mapreduce.task.io.sort.factor</name>
<value>10</value>
<description>The number of streams to merge at once while sorting
files. This determines the number of open file handles.</description>
</property>
<property>
<name>mapreduce.task.io.sort.mb</name>
<value>100</value>
<description>The total amount of buffer memory to use while sorting
files, in megabytes. By default, gives each merge stream 1MB, which
should minimize seeks.</description>
</property>
Кроме того, существует недокументированное свойство конфигурации, mapreduce.map.combine.minspills
, которая определяет минимальное количество разливов, необходимых перед запуском объединителя. Значение по умолчанию - 3
, если не указано.
Возможно, что вы можете настроить эти свойства конфигурации как раз справа, чтобы установить условия для запуска достаточного количества разливов, чтобы превысить mapreduce.map.combine.minspills
и, следовательно, гарантировать хотя бы один вызов объединителя. Однако я не могу рекомендовать это, потому что это было бы очень хрупким. Логика будет чрезвычайно чувствительна к внешним факторам, таким как размер входных данных. Кроме того, он будет опираться на конкретные детали реализации текущей базы данных MapReduce. Внутренние алгоритмы могут быть изменены, и эти изменения могут нарушить ваши предположения. Фактически нет публичного API для принудительного запуска комбайнера.
Кроме того, имейте в виду, что в отличие от редуктора сумматор не может получить полную картину всех значений, связанных с определенным ключом. Если несколько задач карты обрабатывают записи с одним и тем же ключом, то редуктор - единственное место, где гарантировано, что все эти значения будут сгруппированы вместе. Даже в рамках одной задачи карты объединитель может выполняться несколько раз с различными подмножествами значений ключа, вытаскиваемых из обрабатываемого входного разделения.
Для более стандартного решения проблемы экспорта данных из Hadoop в реляционную базу данных рассмотрите DBOutputFormat или Sqoop.
Ответ должен быть очевиден: сделайте это в редукторе (добавьте один). –
Причина, по которой я не хочу это делать в редукторе, заключается в том, что я не хочу, чтобы мое приложение проходило дорогостоящую фазу перетасовки/сортировки. –