2012-02-29 7 views
1

В настоящее время я читаю статью, и я пришел к выводу, что писатели говорят, что у них есть несколько массивов в памяти для каждой задачи карты, и когда задача карты заканчивается, они выводят этот массив.Hadoop: Возможно ли иметь в структуре памяти функцию карты и суммировать их?

Это документ, который я имею в виду: http://research.google.com/pubs/pub36296.html

Это выглядит несколько по битам, не MapReduce, что нужно сделать, но я пытаюсь реализовать этот проект, и я пришел к точке были это только решение. Я пробовал много способов использовать общую философию уменьшения карты, которая обрабатывает каждую строку и выводит пару ключевых значений, но таким образом у меня есть для каждой строки ввода много тысяч контекстных записей, и ее занимает много времени, чтобы написать их. Таким образом, моя задача карты является узким местом. Эти контекстные записи стоят дорого.

Если я сделаю это по-своему, мне удастся значительно сократить количество пар ключ-значение. Поэтому мне нужно найти способ иметь в структурах памяти для каждой задачи карты. Я могу определить эти структуры как статические в функции установки, но я могу найти способ сказать, когда заканчиваются задачи карты, чтобы я мог выводить эту структуру. Я знаю, это звучит немного странно, но это единственный способ работать эффективно.

Это то, что они говорят, в этой статье

При загрузке каждый преобразователь загружает набор разделенных точками, которые будут рассматриваться для каждого заказанного атрибута. Для каждого узла n ∈ N и атрибута X, картограф поддерживает таблицу Tn, X ключей- пары значений.

После обработки всех входных данных, то картостроители OUT- пут ключей вида п, X и значение v, Tn, X [v]

Вот некоторые правки после ответа Шона:

Я использую комбайнер в своей работе. Дело в том, что эти команды context.write (Text, Text) в моей функции карты действительно занимают много времени. Мой вход - файлы csv или файлы arff. В каждой строке есть пример. Мои примеры могут иметь до тысячи атрибутов. Я выводил для каждого атрибута пары ключ-значение в форме < (n, X, u), Y>, где имя узла (я создаю дерево решений), X - это имя атрибута, u - значение атрибута, а Y - некоторая статистика в текстовом формате. Как вы можете сказать, если у меня есть 100 000 атрибутов, мне нужно будет иметь 100 000 команд context.write (Text, Text) для каждого примера. Выполняя мою задачу карты без этих команд, она работает как ветер. Если я добавлю команду context.write, это займет навсегда. Даже для 2000 тысяч наборов атрибутов. Мне кажется, что я пишу в файлах, а не в памяти. Поэтому мне действительно нужно уменьшить эти записи. Агрегация их в памяти (в функции карты, а не в объединителе) необходима.

ответ

1

Добавление другого ответа, так как я вижу точку вопроса сейчас, я думаю.

Чтобы узнать, когда закончится задача карты, ну, вы можете переопределить close(). Я не знаю, это то, чего ты хочешь. Если у вас есть 50 карт, 1/50-й из входных данных, которые каждый видит, неизвестен или не гарантирован. Это нормально для вашего случая использования - вам просто нужен каждый рабочий, чтобы агрегировать статистику в памяти за то, что он видел и выводил?

Тогда ваша процедура прекрасна, но, вероятно, не сделает вашу структуру данных в памяти static - никто не сказал, что два Mapper s не будут работать в одном загрузчике классов JVM.

Более распространенная версия этого шаблона воспроизводится в Reducer, где вам необходимо собрать информацию по некоторым известным подмножествам входящих ключей, прежде чем вы сможете создать одну запись. Вы можете использовать разделитель и тот факт, что ключи отсортированы, чтобы знать, что вы видите все это подмножество для одного рабочего, и можете знать, когда это будет сделано, потому что появится новое другое подмножество. Тогда довольно легко собрать данные в памяти при обработке подмножества, вывести результат и очистить его, когда появится новое подмножество.

Я не уверен, что здесь работает, так как узкое место происходит до Reducer.

+0

да, это именно то, что я хочу. агрегировать и выводить на редуктор (и, возможно, иметь объединитель). Закрыть кажется хорошим решением. И да, если статические переменные могут вызвать некоторые проблемы. Спасибо что подметил это. Поэтому я попытаюсь сделать что-то вроде context.write внутри close (я просто проверил, что он называется очисткой). Я сообщу вам, если это сработает. Я просто попробовал написать несколько более мелких текстовых переменных, и это стало быстрее. Спасибо за ваши ответы. Они не могли быть более полезными. – jojoba

+0

Хорошо, я сделал это. Это полностью описано в статье. Это происходит намного быстрее. Мне все еще нужно немного оптимизировать мой код, и все будет хорошо. Большое спасибо за ваши предложения – jojoba

1

Не зная о деталях вывода данных, я не могу быть уверенным, что это поможет, но это похоже на то, с чем и состоит комбинатор. Это похоже на миниатюрный редуктор (на самом деле реализация комбайнера - это еще одна реализация Reducer), прикрепленная к выходу Mapper. Его цель - собирать записи о выходе карты в память и пытаться объединить их перед записью на диск и затем собирать по Reducer.

Классический пример - подсчет значений. Вы можете вывести «ключ, 1» из вашей карты, а затем добавить 1s в редукторе, но это включает вывод «ключа 1» 1000 раз из картографа, если ключ появляется 1000 раз, когда «key, 1000» будет достаточно , Объединитель делает это.Конечно, это применимо только тогда, когда рассматриваемая операция ассоциативна/коммутативна и может повторяться повторно без побочного эффекта - добавление является хорошим примером.

Другой ответ: в Mahout мы реализуем много вещей, которые являются странными, немного сложными и очень медленными, если сделать простой способ. Вытягивание трюков, таких как сбор данных в памяти в Mapper, - это незначительный, а иногда и необходимый грех, поэтому в этом нет ничего плохого. Это означает, что вам действительно нужно знать семантику, которую Hadoop гарантирует, хорошо тестирует и думает о нехватке памяти, если не осторожна.

+0

Спасибо, Шон. См. Мои изменения для получения дополнительной информации. Я использую комбайнер. Кстати, я использовал Mahout, и я прочитал вашу книгу. Я не могу дождаться, чтобы увидеть несколько более поздних версий: D. – jojoba

+0

(Я предполагаю, что у вас есть сжатие вывода на карту.) Может быть, вы можете хэшировать имена или функции или статистику для некоторого меньшего идентификатора, который может быть восстановлен позже? Или, по крайней мере, что-то более компактное, чем обычный текст. –

+0

Ну, у меня не было сжатия, но я сделал это сейчас, и ничего не произошло. Это не похоже на то, что у меня проблема с размером моих текстовых переменных, но с количеством записей. Разве нет способа сказать, когда задача карты закончится? Возможно, у реализации Google есть способ узнать это и почему она используется. Я очень ценю ваш интерес. – jojoba