2012-01-16 3 views
5

Sono nuovo di Hadoop e sto cercando di capire come funziona. Per quanto riguarda un esercizio dovrei implementare qualcosa di simile a WordCount-Example. L'attività consiste nel leggere diversi file, eseguire il WordCount e scrivere un file di output per ciascun file di input. Hadoop utilizza un combinatore e mischia l'output della parte della mappa come input per il riduttore, quindi scrive un file di output (credo per ogni istanza in esecuzione). Mi stavo chiedendo se è possibile scrivere un file di output per ogni file di input (quindi mantieni le parole di inputfile1 e scrivi il risultato su outputfile1 e così via). È possibile sovrascrivere la Combiner-Class o c'è un'altra soluzione per questo (non sono sicuro se questo dovrebbe essere risolto in un Hadoop-Task ma questo è l'esercizio).Hadoop MapReduce - un file di output per ciascun input

Grazie ...

risposta

1

map.input.file parametro di ambiente ha il nome del file che il mapper sta elaborando. Ottieni questo valore nel mapper e usalo come chiave di output per il mapper e poi tutto il k/v da un singolo file per andare a un riduttore.

Il codice nel mappatore. BTW, io sto usando la vecchia API MR

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

e utilizzare MultipleOutputFormat, questo permette di scrivere i file di output per il lavoro. I nomi dei file possono essere derivati ​​dalle chiavi e dai valori di output.

+0

grazie, penso che sia la migliore idea. Forse userò la vecchia API perché sembra più facile da gestire, ma prima darò un'occhiata a 0.20 – spooky

0

Hadoop 'pezzi' dati in blocchi di dimensioni configurato. L'impostazione predefinita è 64 MB di blocchi. Potresti vedere dove ciò causa problemi per il tuo approccio; Ogni mappatore può ottenere solo un pezzo di un file. Se il file è inferiore a 64 MB (o qualsiasi valore è configurato), ogni mapper otterrà solo 1 file.

Ho avuto un vincolo molto simile; Avevo bisogno di una serie di file (uscita dal precedente riduttore in catena) per essere interamente elaborati da un singolo mapper. Io uso il fatto di < 64 MB nella mia soluzione La spinta principale della mia soluzione è che l'ho configurato per fornire al programma di mappatura il nome del file che era necessario elaborare, e il mappatore interno aveva caricato/letto il file. Ciò consente a un singolo mappatore di elaborare un intero file: non è l'elaborazione distribuita del file, ma con il vincolo di "Non voglio singoli file distribuiti" - funziona. :)

Ho avuto il processo che ha avviato il mio MR scrivere i nomi dei file dei file da elaborare in singoli file. Dove sono stati scritti quei file era la directory di input. Poiché ogni file è < 64 MB, verrà generato un singolo mapper per ogni file. Il processo map verrà chiamato esattamente una volta (poiché c'è solo una voce nel file).
Quindi prendo il valore passato al programma di mappatura e posso aprire il file e fare qualunque mappatura devo fare. Poiché hadoop cerca di essere intelligente su come esegue la mappatura/riduzione dei processi, potrebbe essere necessario specificare il numero di riduttori da utilizzare in modo che ogni mappatore vada a un singolo riduttore. Questo può essere impostato tramite la configurazione mapred.reduce.tasks. Lo faccio tramite job.setNumReduceTasks("mapred.reduce.tasks",[NUMBER OF FILES HERE]);

Il mio processo aveva alcuni requisiti/vincoli aggiuntivi che potrebbero aver reso attraente questa soluzione specifica; ma per un esempio di 1: in 1: out; L'ho fatto, e le basi sono esposte sopra.

HTH

+0

Grazie per l'input. Con setNumReduceTasks ottengo il maggior numero di file di output di cui ho bisogno. Tuttavia, l'input per i riduttori viene ancora mescolato/mescolato. Ho controllato l'output del mio mapper e sembra che un mappatore stia elaborando due file (ma questo non dovrebbe essere il problema). Ma anche i risultati dei mappatori che elaborano un solo file vengono mescolati con i risultati degli altri mappatori.Posso impedire a Hadoop di farlo (shuffle/combine? Forse impostare la classe combinata?) Hai appena ricevuto tutti i nomi di file e li hai passati al mapper? O mi sta sfuggendo qualcosa? Forse un altro conf-value da impostare? – spooky

+0

Per forzare un riduttore specifico, fare in modo che ciascun mappatore usi una chiave specifica durante la scrittura dell'output. Le stesse chiavi andranno allo stesso mapper. È possibile passare un valore diverso nel conf per ogni lavoro, quindi utilizzare tale valore come chiave. Ciò comporterebbe l'output per ogni mapper andando a un singolo riduttore (nella mia esperienza). – Nija

+1

Il passaggio di nomi di file a un programma di mappatura in modo che un file venga elaborato da un singolo mapper non è l'approccio efficace. Non c'è localizzazione dei dati e ci saranno dati più mescolanti. Un modo per risolverlo è raggruppare i file dipendenti in 1 (gz, tar) e restituire false dal metodo isInplice di FileInputFormat #. –