Hadoop MapReduce: соответствующий размер входных файлов?

У меня есть наборы данных величиной 3-значных ГБ или даже 1 или 2-значный ТБ. Поэтому входные файлы представляют собой список файлов размером 10 ГБ. Моя карта уменьшает работу в hadoop и обрабатывает все эти файлы, а затем дает только один выходной файл (с агрегированной информацией).

Мои вопросы:

  • Каков подходящий размер файла для настройки инфраструктуры hadoop/mapreduce из Apache? Я слышал, что более крупные размеры файлов более предпочтительны, чем маленькие. Есть идеи? Единственное, что я точно знаю, это то, что hadoop считывает блоки, каждый по 64 МБ по умолчанию. Поэтому было бы неплохо, если бы размер файла был мультипликатором 64 МБ.

  • В настоящее время мое приложение записывает выходной файл только в один файл. Размер файла - это, конечно, 3-значный гигабит. Мне интересно, насколько эффективно я могу разбить файл. Конечно, я могу использовать некоторые инструменты unix для выполнения этой работы. Но предпочтительнее ли это делать непосредственно в hadoop?

спасибо для ваших комментариев!

P.S.: Я не сжимаю файлы. Формат файлов входных файлов - text/csv.

Ответ 1

Если вы не сжимаете файлы, тогда hasoop обработает ваши большие файлы (скажем, 10G), с количеством карт, связанных с размером блока файла.

Скажите, что размер вашего блока равен 64 М, тогда у вас будет ~ 160 карт, обрабатывающих этот 10G файл (160 * 64 ~ = 10G). В зависимости от того, насколько ЦП интенсивно использует вашу картографическую логику, это может быть приемлемый размер блоков, но если вы обнаружите, что ваши мапперы выполняются в субминутные моменты времени, то вам может понадобиться увеличить работу, выполняемую каждым преобразователем (путем увеличения размера блока до 128, 256, 512 м - фактический размер зависит от того, как вы собираетесь обрабатывать данные).

Чем больше размер блоков, тем меньше количество карт, используемых для обработки файла 10G. Разумеется, вы можете увеличить минимальный размер разделения, используемый TextInputFormat, но тогда вы, скорее всего, столкнетесь с более низкой локальностью данных, поскольку картограф может обрабатывать 2 или более блоков, которые могут не все находиться локально на этом node.

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

Ответ 2

Размер входных файлов:

Один из способов настроить это - посмотреть, насколько быстро выполняются задачи по карте. Каждая задача карты будет содержать 1 файл в качестве входных данных, и если они завершатся менее чем за 30-40 секунд, вы должны рассмотреть возможность увеличения размера каждого файла, чтобы у каждого картографа было больше работы. Это связано с тем, что задача карты занимает около 30 секунд для инициализации перед выполнением какой-либо реальной работы.

Это также зависит от того, сколько задач карты может выполнять ваш кластер за один раз. Вы можете попытаться настроить размер файлов и блоков так, чтобы вы могли использовать как можно больше задач карты. См. Это сообщение в блоге для более идей: http://www.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/

Размер выходных файлов:

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

Сжатие:

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

Кроме того, сжимайте промежуточный вывод вашей задачи карты (вывод из задачи карты перед тем, как перейти к редуктору). Это повысит производительность аналогичным образом. Это делается установкой mapred.compress.map.output=true.

Ответ 3

Hadoop делит работу на основе размера разделения ввода. Он делит ваш общий размер данных на ваш размер разделения и определяет, как он определяет, сколько заданий по карте будет выполнено. Общий консенсус в том, что вы хотите от 10 до 100 карт на машину; от http://hadoop.apache.org/common/docs/r0.18.3/mapred_tutorial.html

Количество карт обычно определяется общим размером входов, то есть общим количеством блоков входных файлов. Правильный уровень parallelism для карт, по-видимому, составляет около 10-100 карт на node, хотя для него было задано до 300 карт для задач с очень компактными картами. Настройка задачи занимает некоторое время, поэтому лучше всего, чтобы карты выполнялись не менее минуты.

В некоторых форматах ввода вы можете установить размер разделения, по умолчанию большинство (включая TextInputFormat) создают одну карту на блок. Таким образом, если у вас есть несколько разных файлов, вы получите больше неполных блоков размером 64 МБ, которые являются пустой тратой карты.

Обработка одного гигантского файла намного эффективнее обработки нескольких файлов. Настройка для задания занимает больше времени, когда ему приходится учитывать несколько файлов. Ядро hadoop было действительно сосредоточено вокруг небольшого количества больших файлов. Кроме того, HDFS настроен для обработки небольшого количества больших файлов, и чем больше файлов у вас больше, тем больше наметьте его, чтобы отслеживать их.