Я не уверен, что это хороший вариант использования Hadoop, если только у вас нет тонн результатов поиска для обработки, и на обработку приходится значительная часть всей программы. Сам поиск не может быть выполнен параллельно: только обработка в вашем цикле for.
Если вы хотите обработать один поиск параллельно в Hadoop, вам сначала нужно будет выполнить поиск вне Hadoop ** и вывести результаты в текстовый файл - например, список идентификаторов. , Затем напишите маппер, который берет ID, выбирает фотографию и выполняет обработку, которую вы в данный момент выполняете в цикле for, испуская строку с вашими выбранными атрибутами (которую вы сейчас печатаете в System.out
). Hadoop будет запускать этот маппер индивидуально для каждого идентификатора в вашем списке результатов.
Я не думаю, что это будет стоить того, если вы не планируете какую-то другую обработку. Некоторые альтернативы для рассмотрения:
Используйте map-reduction для параллельного выполнения множества различных поисков. Ваша программа практически не изменится - она будет работать внутри функции карты вместо цикла main (). Или ваш поиск может происходить в маппере с выдачей результатов, а ваша обработка может происходить в редукторе. Ваш ввод будет список поисковых терминов.
Забудьте об уменьшении карты и просто запустите обработку параллельно, используя пул потоков. Проверьте различные Executors
в java.util.concurrent
.
** Альтернативный, хакерский способ заставить все это работать "внутри" Hadoop - запустить поиск внутри функции карты, выдавая результаты один за другим. Используйте входной файл с одной строкой текста - фиктивным значением, чтобы ваш маппер запускался только один раз. Затем выполните выборку изображений в редукторе вместо картографа.
Обновление
Если у вас есть куча разных идентификаторов групп для поиска, тогда вы можете использовать первый «альтернативный» подход.
Как вы и предлагали, используйте идентификаторы групп и ключи API в качестве ввода. Поместите по одному в каждой строке, разделенные вкладкой или что-то, что вы можете легко разобрать. Вам также придется разделить их на разные файлы, если вы хотите, чтобы они запускались в разных мапперах. Если у вас столько идентификаторов групп, сколько узлов, вы, вероятно, просто захотите поместить одну строку в каждый файл. Используйте TextInputFormat
для своей работы в Hadoop. Строка с идентификатором группы и ключом API будет иметь значение - используйте value.toString().split("\t")
, чтобы разделить ее на две части.
Затем запустите весь поиск внутри картографа. Для каждого результата используйте context.write(key, value)
(или output.collect(key, value)
, в зависимости от вашей версии), чтобы написать идентификатор фотографии в качестве ключа и строку с вашими атрибутами в качестве значения. Оба из них должны быть преобразованы в Text
объекты Hadoop.
Я не собираюсь давать оптовый код для этого - должно быть очень легко просто адаптировать учебник Hadoop MapReduce . Единственные реальные отличия:
Используйте job.setOutputValueClass(Text)
и измените, где написано IntWritable
в
подпись класса картографа:
public static class Map
extends Mapper<LongWritable, Text, Text, Text> {
Просто отключите редуктор. Выньте класс редуктора и измените его:
job.setMapperClass(Map.class);
job.setCombinerClass(Reduce.class);
job.setReducerClass(Reduce.class);
в это:
job.setMapperClass(Map.class);
job.setNumReduceTasks(0);
Если у вас есть конкретные вопросы о том, как заставить это работать, не стесняйтесь спрашивать. Впрочем, сначала приложите усилия для исследования.