Hadoop MapReduce - один выходной файл для каждого ввода - PullRequest
5 голосов
/ 17 января 2012

Я новичок в Hadoop и пытаюсь понять, как это работает.Что касается упражнения, я должен реализовать что-то похожее на пример WordCount.Задача - прочитать несколько файлов, выполнить WordCount и записать выходной файл для каждого входного файла.Hadoop использует объединитель и перетасовывает выходные данные части карты в качестве входных данных для редуктора, а затем записывает один выходной файл (я полагаю, для каждого работающего экземпляра).Мне было интересно, можно ли написать один выходной файл для каждого входного файла (поэтому сохраните слова inputfile1 и запишите результат в outputfile1 и т. Д.).Можно ли переписать класс Combiner или есть другое решение для этого (я не уверен, должно ли это быть решено в Hadoop-Task, но это упражнение).

Спасибо ...

Ответы [ 2 ]

1 голос
/ 17 января 2012

map.input.file параметр окружения имеет имя файла, который обрабатывает маппер.Получите это значение в преобразователе и используйте его в качестве выходного ключа для преобразователя, а затем все k / v из одного файла для перехода к одному преобразователю.

Код в преобразователе.Кстати, я использую старый MR API

@Override
public void configure(JobConf conf) {
    this.conf = conf;
}

@Override.
public void map(................) throws IOException {

        String filename = conf.get("map.input.file");
        output.collect(new Text(filename), value);
}

и использую MultipleOutputFormat, это позволяет записывать несколько выходных файлов для работы.Имена файлов могут быть получены из ключей и значений вывода.

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

Hadoop 'куски' данных в блоки настроенного размера. По умолчанию используется 64 МБ блоков. Вы можете увидеть, где это вызывает проблемы для вашего подхода; Каждый картограф может получить только часть файла. Если размер файла составляет менее 64 МБ (или любое другое настроенное значение), то каждый сопоставитель получит только 1 файл.

У меня было очень похожее ограничение; Мне нужно было, чтобы набор файлов (вывод из предыдущего редуктора в цепочке) был полностью обработан одним маппером. Я использую факт <64MB в моем решении Основная идея моего решения заключается в том, что я настроил его так, чтобы мапперу было предоставлено имя файла, которое необходимо обработать, и он был внутренним для маппера, который загружал / считывал файл. Это позволяет одному мапперу обрабатывать весь файл - это не распределенная обработка файла, но с ограничением «Я не хочу, чтобы отдельные файлы распространялись» - это работает. :) </p>

У меня был процесс, который запустил мой MR, записал имена файлов файлов для обработки в отдельные файлы. Там, где были записаны эти файлы, был каталог ввода. Поскольку размер каждого файла <64 МБ, для каждого файла будет создан один сопоставитель. Процесс <code>map будет вызван ровно один раз (поскольку в файле всего 1 запись).
Затем я беру значение, переданное мапперу, и могу открыть файл и сделать все, что мне нужно. Поскольку hadoop старается быть умным в отношении того, как он выполняет процессы Map / Reduce, может потребоваться указать количество используемых редукторов, чтобы каждый преобразователь переходил к одному редуктору. Это можно установить через конфигурацию mapred.reduce.tasks. Я делаю это через job.setNumReduceTasks("mapred.reduce.tasks",[NUMBER OF FILES HERE]);

У моего процесса были некоторые дополнительные требования / ограничения, которые могли сделать это конкретное решение привлекательным; но для примера 1: в 1: в; Я сделал это, и основы изложены выше.

НТН

...