Использовать имя отношения / имя таблицы / имя файла в MapReduce Hadoop - PullRequest
1 голос
/ 19 января 2011

Есть ли способ использовать имя отношения в MapReduce's Map и Reduce? Я пытаюсь установить значение разницы с помощью MapReduce Hadoop.

Входные данные: 2 файла R и S, содержащие список терминов. (Собираюсь использовать t для обозначения термина)

Цель: Найти R - S, т. Е. Слагаемые в R, а не в S

Подход:

Mapper: Выплевывает t -> R или t -> S, в зависимости от того, идет ли t от R или S. Таким образом, вывод карты имеет t в качестве ключа и имя файла в качестве значения.

Редуктор: если список значений для t содержит только R, то выведите t -> t.

Нужно ли мне как-то помечать термины именем файла? Или есть другой способ?

Исходный код для чего-то, что я сделал для Set Union (в этом случае нигде не нужно имя файла). Просто хотел использовать это как пример, чтобы проиллюстрировать недоступность имени файла в Mapper.

public class Union {
        public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {

                public void map(LongWritable key, Text value, OutputCollector output, Reporter reporter) throws IOException {
                        output.collect(value, value);
                }
        }

        public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text> {

                public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter) throws IOException{
                        while (values.hasNext())
                        {
                                output.collect(key, values.next());
                                break;
                        }
                }
        }

        public static void main(String[] args) throws Exception {
                JobConf conf = new JobConf(Union.class);
                conf.setJobName("Union");
                conf.setOutputKeyClass(Text.class);
                conf.setOutputValueClass(Text.class);

                conf.setMapperClass(Map.class);
                conf.setCombinerClass(Reduce.class);
                conf.setReducerClass(Reduce.class);
                conf.set("mapred.job.queue.name", "myQueue");
                conf.setNumReduceTasks(5);

                conf.setInputFormat(TextInputFormat.class);
                conf.setOutputFormat(TextOutputFormat.class);

                FileInputFormat.setInputPaths(conf, new Path(args[0]));
                FileOutputFormat.setOutputPath(conf, new Path(args[1]));

                JobClient.runJob(conf);
        }
}

Как видите, я не могу определить, какая пара ключ -> значение (входная информация для Mapper) поступила из какого файла. Я пропускаю что-то простое здесь?

Большое спасибо.

1 Ответ

3 голосов
/ 20 января 2011

Я бы реализовал ваш вопрос так же, как вы ответили.Именно так и должен был быть MapReduce.Я полагаю, ваша проблема заключалась в том, чтобы записать в HDFS n-раз одинаковое значение? РЕДАКТИРОВАТЬ: Вставлено из моего комментария внизу

Ах, я понял;) Я не очень знаком со "старым" API, но вы можете "запрос"ваш репортер с:

reporter.getInputSplit();

Это возвращает вам интерфейс с именем InputSplit.Это легко можно преобразовать в «FileSplit».А внутри объекта FileSplit вы можете получить Path с помощью: "split.getPath ()".А из объекта Path вам просто нужно вызвать метод getName ().Так что этот фрагмент должен работать на вас:

FileSplit fsplit = reporter.getInputSplit(); // maybe cast it down to FileSplit if needed..
String yourFileName = fsplit.getPath().getName();
...