Hadoop MapReduce предоставляет вложенные каталоги в качестве входных данных для задания.

Я работаю над заданием, которое обрабатывает вложенную структуру каталогов, содержащую файлы на нескольких уровнях:

one/
├── three/
│   └── four/
│       ├── baz.txt
│       ├── bleh.txt
│       └── foo.txt
└── two/
    ├── bar.txt
    └── gaa.txt

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

Я читал о job.addInputPathRecursively(..), но, кажется, это устарело в более поздних выпусках (я использую hadoop 1.0.2). Я написал некоторый код для обхода папок и добавления каждого каталога с job.addInputPath(dir), который работал до тех пор, пока задание не вышло из строя при попытке обработки каталога в качестве входного файла по какой-то причине, например. - попытка fs.open(split.getPath()), когда split.getPath() является каталогом (это происходит внутри LineRecordReader.java).

Я пытаюсь убедить себя, что должен быть более простой способ предоставить задание с вложенной структурой каталогов. Любые идеи?

РЕДАКТИРОВАНИЕ — по-видимому, в этом есть открытая ошибка.


person sa125    schedule 18.04.2012    source источник
comment
Неужели так сложно использовать FileSystem#listStatus() и добавлять их рекурсивно?   -  person Thomas Jungblut    schedule 18.04.2012
comment
Я решаю это аналогичным образом - написал рекурсивный код, который проходит по подкаталогам и добавляет все файлы во входные пути.   -  person David Gruzman    schedule 18.04.2012
comment
@ThomasJungblut это мой текущий подход. Мне просто кажется странным, что эта функция не встроена. Другая проблема, с которой я сталкиваюсь, заключается в том, что Hadoop падает, когда обращается к подпапке без каких-либо файлов в ней, просто к другим папкам (например, one и one/three в моем примере). Итак, в основном мне нужно реализовать логику, которая будет рекурсивно добавлять папки, если они только не имеют в них других папок вместо файлов (все еще нужно пройтись по их содержимому, чтобы добавить вложенные файлы). Кажется, много хлопот только для того, чтобы устроиться на работу.   -  person sa125    schedule 19.04.2012
comment
Вы можете написать PathFilter, который принимает только файлы, а затем использовать метод FileInputFormat.setInputPathFilter — hadoop.apache.org/common/docs/current/api/org/apache/hadoop/   -  person Chris White    schedule 10.05.2012
comment
возможный дубликат использование FileStatus для рекурсивного каталога   -  person Suvarna Pattayil    schedule 10.11.2013


Ответы (5)


Я не нашел никакого документа по этому поводу, но */* работает. Итак, -input 'path/*/*'.

person Cheng    schedule 13.08.2012
comment
Вы уверены, что это не расширяется в bash (или вашей оболочке) и не запускает множество экземпляров Hadoop? - person jbu; 08.06.2013
comment
У меня есть одинарные кавычки вокруг них. - person Cheng; 08.06.2013
comment
Запуск ps -aux поможет устранить проблему, упомянутую @jbu. - person gokul_uf; 15.09.2015

импортировать org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

FileInputFormat.setInputDirRecursive (задание, правда);

Нет, спасибо, зовите меня просто ЛэйФэн!

person backingwu    schedule 31.12.2014

Я считаю, что рекурсивный просмотр данных может быть опасным, поскольку могут быть устаревшие файлы журнала из distcp или чего-то подобного. Предлагаю альтернативу:

Выполните рекурсивный обход в командной строке, а затем передайте пути в параметре, разделенном пробелами, в вашу программу MapReduce. Возьмите список из argv:

$ hadoop jar blah.jar "`hadoop fs -lsr recursivepath | awk '{print $8}' | grep '/data.*\.txt' | tr '\n' ' '`"

Извините за долгий бред, но он выполняет свою работу. Вы можете обернуть вещь в сценарий bash, чтобы разбить ее на переменные.

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

person Donald Miner    schedule 18.04.2012
comment
Спасибо за это. Знаете ли вы, есть ли какая-либо причина делать это таким образом, а не FileInputFormat.addInputPaths (файл, разделенный запятыми, из приведенного выше bash)? - person dranxo; 02.08.2012
comment
Интересно, а почему? Я новичок в Hadoop, но уже столкнулся с этой проблемой -lsr. - person dranxo; 02.08.2012

Не знаю, актуально ли это, но, по крайней мере, в hadoop 2.4.0 вы можете установить для свойства mapreduce.input.fileinputformat.input.dir.recursive значение true, и это решит твоя проблема.

person Eitan Illuz    schedule 04.12.2014

просто используйте FileInputFormat.addInputPath("с шаблоном файла"); Я пишу свою первую программу для анализа графов, где ввод осуществляется из каталога различий в формате .gz ... у меня это сработало !!!

person Vishal Kumar    schedule 27.04.2012
comment
использование шаблона имени - один из способов избежать проблемы с вложенными каталогами. - person hakunami; 08.05.2014