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

MapReduce-Typen und -Formate verstehen

Hadoop verwendet das MapReduce-Programmiermodell für die Datenverarbeitung von Eingabe und Ausgabe für die Karte und zum Reduzieren von Funktionen, die als Schlüssel-Wert-Paare dargestellt werden. Sie unterliegen der parallelen Ausführung von Datensätzen, die sich auf einer Vielzahl von Maschinen in einer verteilten Architektur befinden. Das Programmierparadigma ist im Wesentlichen funktionaler Natur beim Kombinieren unter Verwendung der Technik des Abbildens und Reduzierens. Dieser Artikel stellt das MapReduce-Modell vor und insbesondere, wie Daten in verschiedenen Formaten verwendet werden, von einfachem Text bis hin zu strukturierten Binärobjekten.

MapReduce-Typen

Zuordnung ist die Kerntechnik zur Verarbeitung einer Liste von Datenelementen, die in Paaren von Schlüsseln und Werten vorliegen. Die Zuordnungsfunktion gilt für einzelne Elemente, die als Schlüssel-Wert-Paare einer Liste definiert sind, und erzeugt eine neue Liste. Die allgemeine Idee der Map- und Reduce-Funktion von Hadoop lässt sich wie folgt veranschaulichen:

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

Die Eingabeparameter des Schlüssel-Wert-Paares, dargestellt durch K1 bzw. V1, unterscheiden sich vom Ausgabepaartyp:K2 und V2. Die Reduce-Funktion akzeptiert das gleiche Format, das von der Map ausgegeben wird, aber die Ausgabeart der Reduce-Operation ist wieder anders:K3 und V3. Die Java-API dafür lautet wie folgt:

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

Der OutputCollector ist die verallgemeinerte Schnittstelle des Map-Reduce-Frameworks, um das Sammeln von Daten zu erleichtern, die entweder vom Mapper ausgegeben werden oder der Reduzierer . Diese Ausgaben sind nichts anderes als Zwischenausgaben des Jobs. Daher müssen sie mit ihrem Typ parametriert werden. Der Reporter erleichtert der Map-Reduce-Anwendung, den Fortschritt zu melden und Zähler und Statusinformationen zu aktualisieren. Wenn jedoch die Combine-Funktion verwendet wird, hat sie die gleiche Form wie die Reduce-Funktion und die Ausgabe wird der Reduce-Funktion zugeführt. Dies kann wie folgt veranschaulicht werden:

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

Beachten Sie, dass die Funktionen Combine und Reduce den gleichen Typ verwenden, außer in den Variablennamen, wo K3 K2 und V3 V2 ist.

Die Partitionsfunktion arbeitet mit den Schlüsselwert-Zwischentypen. Es steuert die Partitionierung der Schlüssel der Zwischenabbildungsausgaben. Der Schlüssel leitet die Partition unter Verwendung einer typischen Hash-Funktion ab. Die Gesamtzahl der Partitionen entspricht der Anzahl der Reduzierungsaufgaben für den Job. Die Partition wird nur durch den Schlüssel bestimmt, der den Wert ignoriert.

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

Dies ist kurz gesagt die Essenz der MapReduce-Typen.

Eingabeformate

Hadoop muss eine Vielzahl von Formaten akzeptieren und verarbeiten, von Textdateien bis hin zu Datenbanken. Ein Teil der Eingabe, der als Eingabeaufteilung bezeichnet wird , wird von einer einzigen Karte verarbeitet. Jede Teilung wird weiter in logische Datensätze unterteilt, die der Map zur Verarbeitung in Schlüssel-Wert-Paaren übergeben werden. Im Zusammenhang mit Datenbanken bedeutet die Aufteilung das Lesen einer Reihe von Tupeln aus einer SQL-Tabelle, wie dies beim DBInputFormat der Fall ist und Erstellen von LongWritables enthält Datensatznummern als Schlüssel und DBWritables als Werte. Die Java-API für Eingabeaufteilungen lautet wie folgt:

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

Der InputSplit stellt die von einem Mapper zu verarbeitenden Daten dar . Es gibt die Länge in Bytes zurück und hat eine Referenz auf die Eingangsdaten. Er stellt eine Byte-orientierte Sicht auf die Eingabe dar und liegt in der Verantwortung des RecordReader des Jobs, um diese zu bearbeiten und eine datensatzorientierte Sicht darzustellen. In den meisten Fällen beschäftigen wir uns nicht mit InputSplit direkt, weil sie von einem InputFormat erstellt werden . Dafür ist das InputFormat zuständig um die Eingabeaufteilungen zu erstellen und sie in Datensätze aufzuteilen.

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

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

Der JobClient ruft getSplits() auf -Methode mit der entsprechenden Anzahl von Split-Argumenten. Die angegebene Zahl ist ein Hinweis, da die tatsächliche Anzahl der Splits von der angegebenen Zahl abweichen kann. Sobald der Split berechnet ist, wird er an den Jobtracker gesendet. Der Jobtracker plant Zuordnungsaufgaben für die Tasktracker unter Verwendung des Speicherorts. Der Tasktracker übergibt dann die Teilung, indem er getRecordReader() aufruft Methode auf dem InputFormat um RecordReader zu erhalten für die Teilung.

Das FileInputFormat ist die Basisklasse für die Dateidatenquelle. Es ist dafür verantwortlich, die Dateien zu identifizieren, die als Job-Input enthalten sein sollen, und die Definition für die Generierung der Aufteilung.

Hadoop umfasst auch die Verarbeitung unstrukturierter Daten, die häufig im Textformat vorliegen. Das TextInputFormat ist das Standard-InputFormat für solche Daten.

Das SequenceInputFormat nimmt binäre Eingaben auf und speichert Folgen von binären Schlüssel-Wert-Paaren.

Auf ähnliche Weise bietet DBInputFormat die Möglichkeit, Daten aus einer relationalen Datenbank mit JDBC zu lesen.

Ausgabeformate

Die Ausgabeformatklassen ähneln ihren entsprechenden Eingabeformatklassen und arbeiten in umgekehrter Richtung.

Zum Beispiel das TextOutputFormat ist das Standardausgabeformat, das Datensätze als reine Textdateien schreibt, während Schlüsselwerte beliebige Typen haben können, und sie durch Aufrufen von toString() in einen String umwandelt Methode. Das Schlüsselwertzeichen wird durch das Tabulatorzeichen getrennt, obwohl dies angepasst werden kann, indem die Trennereigenschaft des Textausgabeformats geändert wird.

Für die binäre Ausgabe gibt es SequenceFileOutputFormat um eine Folge von binären Ausgaben in eine Datei zu schreiben. Binäre Ausgaben sind besonders nützlich, wenn die Ausgabe zur Eingabe für einen weiteren MapReduce-Job wird.

Die Ausgabeformate für relationale Datenbanken und nach HBase werden von DBOutputFormat gehandhabt . Es sendet die reduzierte Ausgabe an eine SQL-Tabelle. Zum Beispiel das TableOutputFormat von HBase ermöglicht dem MapReduce-Programm, mit den in der HBase-Tabelle gespeicherten Daten zu arbeiten, und verwendet sie zum Schreiben von Ausgaben in die HBase-Tabelle.

Schlussfolgerung

Dies ist kurz gesagt der springende Punkt bei MapReduce-Typen und -Formaten. Weitere Informationen zu ihnen finden Sie in der Auflistung in der Referenz unten. Es gibt viele komplizierte Details zu den Funktionen der Java-APIs, die erst klarer werden, wenn man in die Programmierung eintaucht. Weitere Einzelheiten finden Sie in der Apache Hadoop Java API-Dokumentation und beginnen Sie mit dem Programmieren einiger Praktiken.

Referenzen

  • Tom White, Hadoop The Definitive Guide , O'Reilly
  • Apache Hadoop Java API-Dokumentation