Есть две проблемы: во-первых, каждый файл (на начальном этапе) должен обрабатываться целиком: преобразователь, который видит первый байт, должен обрабатывать все остальное в этом файле.Другая проблема заключается в локальности: для максимальной эффективности вы хотите, чтобы все блоки для каждого такого файла находились на одном хосте.
Обработка файлов в целом:
Один простойХитрость заключается в том, чтобы на первом этапе маппер обрабатывал список имен файлов , а не их содержимое.Если вы хотите, чтобы запустилось 50 заданий карты, создайте по 50 файлов каждый с этой долей имен файлов.Это легко и работает с Java или потоковым Hadoop.
В качестве альтернативы используйте неразделимый формат ввода, такой как NonSplitableTextInputFormat
.
Для получения дополнительной информации см. " Как обрабатывать файлы, по одному на карту? "и " Как мне заставить каждую из моих карт работать с одним полным входным файлом? " в Wiki Hadoop.
Местонахождение:
Это оставляетпроблема, однако, в том, что блоки, с которых вы читаете, распределяются по всей HDFS: обычно повышение производительности, здесь реальная проблема.Я не верю, что есть какой-либо способ связать определенные блоки в HDFS.
Можно ли разместить файлы в локальном хранилище каждого узла?На самом деле это самый производительный и самый простой способ решить эту проблему: пусть каждая машина запускает задания для обработки всех файлов, например, /data/1/**/*.data
(будучи настолько умным, насколько вы хотите эффективно использовать локальные разделы и количество ядер ЦП).
Если файлы в любом случае исходят из SAN или, скажем, s3, попробуйте просто потянуть оттуда напрямую: он создан для обработки роя.
Примечание по использованию первого трюка: Еслинекоторые файлы намного больше других, поместите их в список с самым ранним именем, чтобы избежать проблем с умозрительным исполнением.В любом случае вы можете отключить спекулятивное выполнение для таких заданий, если задачи надежны и не хотите, чтобы некоторые пакеты обрабатывались несколько раз.