Подтвердить что ты не робот

Hadoop: как получить доступ к (многим) фотографиям, которые нужно обработать с помощью карты/уменьшить?

У меня есть 10M + фотографии, сохраненные в локальной файловой системе. Теперь я хочу пройти через каждый из них, чтобы проанализировать двоичный файл фотографии, чтобы увидеть, если это собака. Я в основном хочу сделать анализ в кластерной среде hadoop. Проблема в том, что как я должен создать вход для метода карты? скажем, в методе карты, new FaceDetection(photoInputStream).isDog() - все это основная логика анализа.

В частности, Должен ли я загружать все фотографии в HDFS? Предположим, что да,

  • Как я могу использовать их в методе map?

  • Можно ли сделать ввод (в map) текстовым файлом, содержащим весь путь фотографии (в HDFS), с каждой строкой, а в методе карты - загрузить двоичный файл например: photoInputStream = getImageFromHDFS(photopath); (На самом деле, какой правильный способ загрузить файл из HDFS во время выполнения метода карты?)

Кажется, я пропустил некоторые знания об основном принципе для hadoop, map/reduce и HDFS, но можете ли вы, пожалуйста, указать мне на этот вопрос, спасибо!

4b9b3361

Ответ 1

как я могу использовать их в методе карты?

Основная проблема заключается в том, что каждый файл будет находиться в одном файле. Так что если у вас есть 10M файлы, у вас будут 10M-карты, что не звучит ужасно разумно. Возможно, вам захочется рассмотреть возможность предварительной сериализации файлов в SequenceFiles (одно изображение на пару с ключом). Это приведет к загрузке данных в задание MapReduce, поэтому вам не нужно писать какой-либо хитрый код. Кроме того, вы сможете сохранить все свои данные в один SequenceFile, если хотите. Hadoop отлично справляется с разделением SequenceFiles.

В основном, как это работает, у вас будет отдельный процесс Java, который принимает несколько файлов изображений, считывает байты лучей в память, а затем сохраняет данные в пару ключевых значений в SequenceFile. Продолжайте и продолжайте писать в HDFS. Это может занять некоторое время, но вам нужно будет сделать это только один раз.


Можно ли сделать ввод (на карту) текстовым файлом, содержащим весь путь фотографии (в HDFS), с каждой строкой, а в методе карты - загрузить двоичный файл: photoInputStream = getImageFromHDFS (photopath ); (На самом деле, какой правильный способ загрузить файл из HDFS во время выполнения метода карты?)

Это не нормально, если у вас есть какой-то разумный кластер (который вы должны, если вы рассматриваете Hadoop для этого), и вы действительно хотите использовать силу Hadoop. Ваше задание MapReduce будет отключено и загружать файлы, но mappers будут работать локально локально с текстовыми файлами, а не с изображениями! Таким образом, в основном, вы собираетесь перетасовывать файлы изображений везде, так как JobTracker не ставит задачи, где находятся файлы. Это повлечет за собой значительное количество сетевых издержек. Если у вас есть 1 ТБ изображений, вы можете ожидать, что многие из них будут транслироваться по сети, если у вас есть несколько узлов. Это может быть не так плохо в зависимости от вашей ситуации и размера кластера (меньше, чем нескольких узлов).

Если вы хотите это сделать, вы можете использовать API FileSystem для создания файлов (вы хотите использовать метод open).

Ответ 2

I have 10M+ photos saved on the local file system.

Предполагая, что для каждого файла в файл последовательности требуется секунда. Для преобразования отдельных файлов в файл последовательности потребуется ~ 115 дней. При параллельной обработке также на одной машине я не вижу большого улучшения, потому что чтение/запись диска будет шеей бутылки с чтением файлов фотографий и написанием файла последовательности. Проверьте статью Cloudera на проблемах с небольшими файлами. Существует также ссылка на script, которая преобразует tar файл в файл последовательности и сколько времени потребовалось для преобразования.

В основном фотографии должны обрабатываться распределенным способом для их преобразования в последовательность. Назад к Hadoop:)

В соответствии с Hadoop - окончательное руководство

Как правило, каждый файл, каталог и блок принимают около 150 байт. Так, например, если у вас было миллион файлов, каждый из которых занимал один блок, вам понадобилось бы не менее 300 МБ памяти.

Таким образом, для непосредственной загрузки 10M файлов потребуется около 3000 МБ памяти для простое хранение пространства имен в NameNode. Забудьте о потоковой передаче фотографий по узлам во время выполнения задания.

Должен быть лучший способ решить эту проблему.


Другой подход - загрузить файлы как есть в HDFS и использовать CombineFileInputFormat, который объединяет небольшие файлы во входной раскол и рассматривает локальность данных при расчете входные расщепления. Преимущество этого подхода в том, что файлы могут быть загружены в HDFS как есть без какого-либо преобразования, а также не так много перетасовки данных по узлам.

Ответ 3

Я был в проекте некоторое время назад (2008?), где мы делали что-то очень похожее на Hadoop. Я считаю, что мы первоначально использовали HDFS для хранения фото, затем мы создали текстовый файл, в котором перечислены файлы для обработки. Концепция заключается в том, что вы используете карту/сокращение, чтобы разбивать текстовый файл на части и распространять его по облаку, позволяя каждому node обрабатывать некоторые файлы на основе той части списка, которую они получают. Извините, я не помню более подробных сведений, но это был общий подход.