Hadoop: как получить доступ ко многим фотографиям, которые будут обработаны картой / уменьшить? - PullRequest
13 голосов
/ 06 января 2012

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

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

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

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

Кажется, я скучаю по некоторым знаниям об основном принципе для hadoop, map/reduce и hdfs, но не могли бы вы указать мне с точки зрения вышеуказанного вопроса, спасибо!

Ответы [ 3 ]

18 голосов
/ 06 января 2012

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

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

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


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

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

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

7 голосов
/ 06 января 2012

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

Предполагается, что для помещения каждого файла в файл последовательности требуется секунда.Преобразование отдельных файлов в файл последовательности займет ~ 115 дней.С параллельной обработкой также на одной машине я не вижу особых улучшений, потому что чтение / запись на диске будет узким местом при чтении файлов фотографий и записи файла последовательности.Ознакомьтесь с этой статьей Cloudera о проблеме small files .Также есть ссылка на скрипт, который конвертирует tar-файл в файл последовательности и сколько времени это заняло для конвертации.

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

В соответствии с Hadoop - Полное руководство

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

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

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


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

0 голосов
/ 06 января 2012

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

...