Database
 sql >> Database >  >> RDS >> Database

Comprensione dei tipi e dei formati di MapReduce

Hadoop utilizza il modello di programmazione MapReduce per l'elaborazione dei dati di input e output per la mappa e per ridurre le funzioni rappresentate come coppie chiave-valore. Sono soggetti all'esecuzione parallela di set di dati situati in un'ampia gamma di macchine in un'architettura distribuita. Il paradigma di programmazione è essenzialmente di natura funzionale nel combinare mentre si utilizza la tecnica della mappa e della riduzione. Questo articolo introduce il modello MapReduce e, in particolare, come vengono utilizzati i dati in vari formati, dal testo semplice agli oggetti binari strutturati.

Tipi MapReduce

Mappatura è la tecnica principale per elaborare un elenco di elementi di dati che si trovano in coppie di chiavi e valori. La funzione mappa si applica ai singoli elementi definiti come coppie chiave-valore di un elenco e produce un nuovo elenco. L'idea generale di mappare e ridurre la funzione di Hadoop può essere illustrata come segue:

map: (K1, V1) -> list (K2, V2)
reduce: (K2, list(V2)) -> list (K3, V3)

I parametri di input della coppia chiave e valore, rappresentati rispettivamente da K1 e V1, sono diversi dal tipo di coppia di output:K2 e V2. La funzione di riduzione accetta lo stesso formato dell'output della mappa, ma il tipo di output di nuovo dell'operazione di riduzione è diverso:K3 e V3. L'API Java per questo è la seguente:

public interface Mapper<K1, V1, K2, V2> extends JobConfigurable,
      Closeable {
   void map(K1 key, V1 value, OutputCollector<K2, V2> output,
      Reporter reporter) throws IOException;
}

public interface Reducer<K2, V2, K3, V3> extends JobConfigurable,
      Closeable {
   void reduce(K2 key, Iterator<V2> values,
      OutputCollector<K3, V3> output, Reporter reporter)throws
         IOException;
}

Il OutputCollector è l'interfaccia generalizzata del framework Map-Reduce per facilitare la raccolta dei dati in uscita sia dal Mapper o il Riduttore . Questi output non sono altro che output intermedi del lavoro. Pertanto, devono essere parametrizzati con i loro tipi. Il Reporter facilita l'applicazione Map-Reduce per segnalare i progressi e aggiornare i contatori e le informazioni sullo stato. Se, invece, viene utilizzata la funzione di combinazione, ha la stessa forma della funzione di riduzione e l'uscita viene inviata alla funzione di riduzione. Questo può essere illustrato come segue:

map: (K1, V1) -> list (K2, V2)
combine: (K2, list(V2)) -> list (K2, V2)
reduce: (K2, list(V2)) -> list (K3, V3)

Si noti che le funzioni di combinazione e riduzione utilizzano lo stesso tipo, tranne che nei nomi delle variabili dove K3 è K2 e V3 è V2.

La funzione di partizione opera sui tipi chiave-valore intermedi. Controlla il partizionamento delle chiavi delle uscite della mappa intermedia. La chiave deriva la partizione utilizzando una tipica funzione hash. Il numero totale di partizioni è uguale al numero di attività di riduzione per il lavoro. La partizione è determinata solo dalla chiave che ignora il valore.

public interface Partitioner<K2, V2> extends JobConfigurable {
   int getPartition(K2 key, V2 value, int numberOfPartition);
}

Questa è l'essenza chiave dei tipi MapReduce in breve.

Formati di input

Hadoop deve accettare ed elaborare una varietà di formati, dai file di testo ai database. Un blocco di input, chiamato input split , viene elaborato da una singola mappa. Ciascuna suddivisione è ulteriormente suddivisa in record logici forniti alla mappa da elaborare in coppia chiave-valore. Nel contesto del database, la divisione significa leggere un intervallo di tuple da una tabella SQL, come fatto da DBInputFormat e produrre LongWritables contenente numeri di record come chiavi e DBWritables come valori. L'API Java per le suddivisioni degli input è la seguente:

public interface InputSplit extends Writable {
   long getLength() throws IOException;
   String[] getLocations() throws IOException;
}

InputSplit rappresenta i dati che devono essere elaborati da un Mapper . Restituisce la lunghezza in byte e ha un riferimento ai dati di input. Presenta una vista orientata ai byte sull'input ed è responsabilità del RecordReader del lavoro per elaborarlo e presentare una vista orientata ai record. Nella maggior parte dei casi, non ci occupiamo di InputSplit direttamente perché sono creati da un InputFormat . È responsabilità di InputFormat per creare le suddivisioni di input e dividerle in record.

public interface InputFormat<K, V> {
   InputSplit[] getSplits(JobConf job, int numSplits) throws
      IOException;

   RecordReader<K, V> getRecordReader(InputSplit split,
      JobConf job, throws IOException;
}

JobClient richiama getSplits() metodo con un numero appropriato di argomenti divisi. Il numero fornito è un suggerimento in quanto il numero effettivo di divisioni potrebbe essere diverso dal numero indicato. Una volta calcolata la divisione, viene inviata al jobtracker. Il jobtracker pianifica le attività della mappa per i tasktracker utilizzando la posizione di archiviazione. Il tasktracker passa quindi la divisione richiamando getRecordReader() metodo su InputFormat per ottenere RecordReader per la divisione.

Il FileInputFormat è la classe base per l'origine dati del file. Ha la responsabilità di identificare i file che devono essere inclusi come input di lavoro e la definizione per generare la divisione.

Hadoop include anche l'elaborazione di dati non strutturati che spesso sono in formato testuale. Il TextInputFormat è il Formato Input predefinito per tali dati.

Il SequenceInputFormat prende input binari e memorizza sequenze di coppie chiave-valore binarie.

Allo stesso modo, DBInputFormat fornisce la capacità di leggere i dati dal database relazionale utilizzando JDBC.

Formati di output

Le classi di formato di output sono simili alle classi di formato di input corrispondenti e funzionano nella direzione inversa.

Ad esempio, il TextOutputFormat è il formato di output predefinito che scrive i record come file di testo normale, mentre i valori-chiave sono di qualsiasi tipo e li trasforma in una stringa invocando toString() metodo. Il carattere del valore-chiave è separato dal carattere di tabulazione, sebbene questo possa essere personalizzato manipolando la proprietà separatore del formato di output del testo.

Per l'output binario, è disponibile SequenceFileOutputFormat per scrivere una sequenza di output binario in un file. Gli output binari sono particolarmente utili se l'output diventa input per un ulteriore lavoro MapReduce.

I formati di output per i database relazionali e per HBase sono gestiti da DBOutputFormat . Invia l'output ridotto a una tabella SQL. Ad esempio, il TableOutputFormat di HBase abilita il programma MapReduce a lavorare sui dati memorizzati nella tabella HBase e lo utilizza per scrivere gli output nella tabella HBase.

Conclusione

Questo è, in breve, il punto cruciale dei tipi e dei formati di MapReduce. Fare riferimento all'elenco nel riferimento di seguito per ottenere maggiori dettagli su di essi. Ci sono molti dettagli intricati sulle funzioni delle API Java che diventano più chiari solo quando ci si immerge nella programmazione. Fare riferimento alla documentazione dell'API Java di Apache Hadoop per maggiori dettagli e iniziare a codificare alcune pratiche.

Riferimenti

  • Tom White, Hadoop La guida definitiva , O'Reilly
  • Documenti dell'API Java di Apache Hadoop