Как получить имя файла / содержимое файла в качестве ввода ключа / значения для MAP при запуске задания Hadoop MapReduce? - PullRequest
5 голосов
/ 19 апреля 2011

Я создаю программу для анализа файлов PDF, DOC и DOCX. Эти файлы хранятся в HDFS.

Когда я запускаю свое задание MapReduce, я хочу, чтобы функция карты имела имя файла в качестве ключа и двоичное содержимое в качестве значения. Затем я хочу создать потоковый ридер, который я могу передать в библиотеку парсера PDF. Как я могу добиться, чтобы пара ключ / значение для фазы карты была filename / filecontents?

Я использую Hadoop 0.20.2

Это старый код, который запускает работу:

public static void main(String[] args) throws Exception {
 JobConf conf = new JobConf(PdfReader.class);
 conf.setJobName("pdfreader");

 conf.setOutputKeyClass(Text.class);
 conf.setOutputValueClass(IntWritable.class);

 conf.setMapperClass(Map.class);
 conf.setReducerClass(Reduce.class);

 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);
}

Я знаю, что существуют другие типы форматов ввода. Но есть ли тот, который делает именно то, что я хочу? Я нахожу документацию довольно расплывчатой. Если он есть, то как должны выглядеть типы ввода функции Map?

Заранее спасибо!

Ответы [ 3 ]

8 голосов
/ 20 апреля 2011

Решением этой проблемы является создание собственного класса FileInputFormat, который делает это.У вас есть доступ к имени входного файла из FileSplit, который получает этот FileInputFormat (getPath).Обязательно отменяйте isSplitable вашего FileInputformat, чтобы всегда возвращать false.

Вам также понадобится пользовательский RecordReader, который возвращает весь файл как одно значение «Record».

Будьте осторожны при работе с файлами, которые слишком велики.Вы эффективно загрузите весь файл в ОЗУ, и по умолчанию для трекера задач доступно только 200 МБ ОЗУ.

1 голос
/ 10 декабря 2013

Вы можете использовать WholeFileInputFormat (https://code.google.com/p/hadoop-course/source/browse/HadoopSamples/src/main/java/mr/wholeFile/?r=3)

В маппере имя файла, которое вы можете получить с помощью этой команды:

public void map(NullWritable key, BytesWritable value, Context context) throws 
IOException, InterruptedException 
{       

Path filePath= ((FileSplit)context.getInputSplit()).getPath();
String fileNameString = filePath.getName();

byte[] fileContent = value.getBytes();

}
1 голос
/ 19 апреля 2011

В качестве альтернативы вашему подходу, возможно, добавьте двоичные файлы непосредственно в hdfs. Затем создайте входной файл, содержащий пути dfs для всех двоичных файлов. Это можно сделать динамически, используя класс FileSystem Hadoop . Наконец, создайте преобразователь, который обрабатывает ввод, открывая входные потоки, снова используя FileSystem.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...