2012-04-18 16 views
21

Sto lavorando a un lavoro che elabora una struttura di directory annidata, contenente i file su più livelli:Hadoop MapReduce fornire le directory nidificate come input di lavoro

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

Quando aggiungo one/ come un percorso di ingresso, nessun file sono elaborato, poiché nessuno è immediatamente disponibile a livello di root.

Ho letto su job.addInputPathRecursively(..), ma questo sembra essere stato deprecato nelle versioni più recenti (sto usando hadoop 1.0.2). Ho scritto del codice per camminare sulle cartelle e aggiungere ogni dir con job.addInputPath(dir), che ha funzionato fino a quando il lavoro si è bloccato durante il tentativo di elaborare una directory come file di input per qualche motivo, ad es. - provare a fs.open(split.getPath()), quando split.getPath() è una directory (questo accade all'interno di LineRecordReader.java).

Sto cercando di convincermi che ci deve essere un modo più semplice per fornire un lavoro con una struttura di directory annidata. Qualche idea?

EDIT - a quanto pare c'è uno open bug su questo.

+3

È così diffuso utilizzare 'FileSystem # listStatus()' e aggiungerli ricorsivamente? –

+0

Lo sto risolvendo in modo simile - ho scritto codice ricorsivo che attraversa le sottodirectory e aggiungo tutti i file ai percorsi di input –

+1

@ThomasJungblut che fondamentalmente è il mio approccio attuale. Trovo strano che questa funzionalità non sia integrata.Un altro problema che sto riscontrando è che haemoop si blocca quando accede a una sottocartella senza file, solo altre cartelle (come 'one' e' one/three' nel mio esempio). Quindi, in pratica, ho bisogno di implementare la logica che aggiungerà le cartelle in modo ricorsivo a meno che ** solo ** abbiano altre cartelle al loro interno, invece dei file (devono ancora percorrere il loro contenuto per aggiungere file nidificati). Sembra un sacco di problemi solo per creare un lavoro. – sa125

risposta

4

Trovo che ricorsivamente i dati possano essere pericolosi poiché potrebbero esserci file di registro persistenti da un distcp o qualcosa di simile. Consentitemi di proporre un'alternativa:

Eseguire la passata ricorsiva sulla riga di comando e quindi passare i percorsi in un parametro delimitato da spazio nel programma MapReduce. Afferra l'elenco dal argv:

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

Scusate per il lungo bash, ma ottiene il lavoro fatto. Potresti avvolgere la cosa in uno script bash per suddividere le cose in variabili.

Personalmente, mi piace l'approccio pass-in-filepath per scrivere i miei lavori mapreduce in modo che il codice stesso non abbia percorsi hardcoded ed è relativamente facile per me configurarlo per essere eseguito su un elenco di file più complesso.

+0

Grazie per questo. Sai se c'è qualche ragione per farlo in questo modo rispetto a FileInputFormat.addInputPaths ("file separato da virgola dalla bash precedente")? – dranxo

+0

Interessante, per quale motivo? Sono abbastanza nuovo per Hadoop, ma mi sono imbattuto in questo problema -lsr già. – dranxo

-1

basta utilizzare FileInputFormat.addInputPath ("with file pattern"); sto scrivendo il mio primo prog di hadoop per l'analisi del grafico in cui l'input proviene da diff dir in formato .gz ... ha funzionato per me !!!

+0

l'utilizzo del modello del nome è un modo per evitare problemi di directory nidificati. – hakunami

14

Non ho trovato alcun documento su questo ma */* funziona. Quindi è -input 'path/*/*'.

+0

sicuro che questo non sia stato espanso in bash (o nella tua shell) e lanciato tonnellate di istanze di hadoop? – jbu

+0

Ho citazioni singole intorno a loro. – Cheng

+0

L'esecuzione di 'ps -aux' aiuterebbe a risolvere il problema menzionato da @jbu –

1

Non so se ancora attuale ma almeno in Hadoop 2.4.0 è possibile impostare la proprietà mapreduce.input.fileinputformat.input.dir.recursive a vero e sarà risolvere il tuo problema.

6

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

FileInputFormat.setInputDirRecursive (job, true);

No grazie, chiamami LeiFeng!

+0

haha ​​Ciao LeiFeng, mi è piaciuto leggere il tuo diario :) – songyy

Problemi correlati