Apache Pig - Universität zu Lübeck

Werbung
1
Apache Pig
Seminararbeit Software Systems Engineering - WS 2012 / 2013
Sebastian Walther - Studiengang Informatik SSE Master
Universität zu Lübeck
Zusammenfassung—Diese
Seminararbeit
soll
einen
einführenden Überblick der Apache Pig Plattform sowie
deren Datenflussanfragesprache Pig Latin vermitteln. Dazu wird
im Einführungskapitel auf die grundlegenden Technologien
eingegangen welche im Zusammenhang mit Apache Pig stehen.
Ebenfalls wird eine Abgrenzung zu der Anfragesprache SQL
angegeben. Darauf folgernd werden die Unterschiede zu einer
reinen MapReduce Lösung beschrieben. Im Praxisteil wird
Pig’s Datenmodell sowie die grundlegenden Sprachelemente
von Pig Latin erläutert. Darauf folgern die Themen Testen,
Performancesteigerung und Benchmarking von Pig Latin
Skripten. Anschließend werden die wichtigsten Punkte in der
Zusammenfassung aufgeführt. Diese Seminararbeit lehnt sich
an das Referenzbuch ”Programming Pig”[1] von Alan Gates an.
Abbildung 1: Subprojekte von Hadoop [3]
Index Terms—Apache Pig, Hadoop, MapReduce, HDFS, Pig
Latin
I. E INF ÜHRUNG
Bei Apache Pig handelt es sich um eine in Java implementierte Plattform, mit der es möglich ist, eine große
Anzahl von Datensätze zu analysieren und zu verarbeiten.
Apache Pig beinhaltet eine eigene Anfragesprache Pig Latin
um Datensätze zu lokalisieren, verarbeiten, aufzubereiten und
abzulegen.
A. Hadoop
Apache Hadoop ist ein Framework welches die Möglichkeit
bietet mehrere Tausend Rechner bezüglich Speicher- und Rechenkapazität zu einer logischen Einheit zusammenzufassen.
Dabei ist das Framework auf Hochverfügbarkeit ausgelegt,
indem es Fehler bereits auf der Anwendungsschicht erkennt
und behebt [2].
Hadoop lässt sich in mehrere zusammenhängende Subprojekte,
wie in Abb.1 darstellen, unterteilen. Zwei dieser Subprojekte
werden von Pig verwendet. Zum einen nutzt Pig das verteilte
Dateisystem HDFS für die Datenverwaltung und zum anderen
wird das Verarbeitungssystem MapReduce eingesetzt um Anfragen auf Daten verteilt durchzuführen. Im Folgenden wird
auf diese zwei Subprojekte eingegangen.
1) MapReduce: Das MapReduce Verfahren dient zur verteilten Verarbeitung von Datensätzen auf einem Cluster von
Rechnern. Das Verfahren arbeitet in den zwei grundlegenden
Phasen Map und Reduce sowie in einer optionalen Phase
Combine. Das in Abb.2 dargestellt MapReduce-Beispiel aus
[1] soll eine Häufigkeitsanalyse von Wörten eines Textes
durchführen.
Die drei Phasen werden anhand des Beispiels im Folgenden
kurz erläutert.
Abbildung 2: MapReduce Beispiel [1]
•
•
Map-Phase: Innerhalb der Map-Phase wird eine zuvor
festgelegte Funktion jeweils auf eine disjunkte Teilmenge
der zu verarbeitenden Daten angewandt. Diese Teilmengen werden jeweils von einem einzelnen Rechner des
Clusters bearbeitet, sodass eine verteilte und parallele
Ausführung der Funktion ermöglicht wird. Im angegebenen Beispiel legt die Map-Funktion für jedes Wort ein
Tupel der Form (Wort, Anzahl) an.
Combine-Phase: Nach der Map-Phase kann optional die
Combine-Phase erfolgen. Dabei werden gleiche Daten
einer Ergebnisliste zusammengefügt um die Netzwerklast
signifikant zu reduzieren. Diese Phase ist nicht in allen
Anwendungsszenarien sinnvoll, kann aber z.B. bei der
Häufigkeitsanalyse aus dem obigen Beispiel seine Berechtigung haben. Hierbei werden Tupel zusammengefasst die den gleichen Wert für Wort“ haben. Die Anzahl
”
wird dann addiert. Aus (Mary,1) und (Mary,1) wird dann
z.B. (Mary,2).
2
Reduce-Phase: In dieser letzten Phase wird auf den
Ergebnislisten der vorherigen Phase, jeweils die ReduceFunktion aufgerufen. Diese reduziert das Datenaufkommen, indem die Funktion beispielsweise nicht benötigte
Daten herausfiltert oder Daten aus mehreren Ergebnislisten zusammenfasst. Auf das obige Beispiel bezogen wird
innerhalb einer Reduce-Funktion jeweils auf Ergebnislisten mehrerer Map-Instanzen zugegriffen. Der Unterscheid
zu der Combine-Phase ist, das die Combine-Funktion
jeweils auf die Ergebnisliste einer Map-Instanz zugreift.
Die Combine- und Reduce-Phase müssen dabei nicht die
gleiche Funktionalität bieten.
2) HDFS: HDFS ist ein verteiltes Dateisystem, welches
Dateien auf einen Cluster von Rechnen repliziert speichert und
verwaltet. Dabei wird mit einem strombasierten Zugriffsverfahren gearbeitet. Ein HDFS besteht aus mehreren Workern
(DataNodes), auf den die Daten abgelegt werden, sowie aus
einem Koordinator (NameNode) welcher für die Haltung der
Metadaten des Dateisystems zuständig ist. Die Metadaten
bestehen dabei größtenteils aus Datei- und Verzeichnisinformationen.
Durch die replizierte Speicherung bietet HDFS eine gewisse
Sicherheit gegenüber ausfallenden DataNodes. Der NameNode
hingegen ist der Single-Point-of-Failure des Dateisystems, wodurch die Verfügbarkeit beeinträchtigt werden kann. Es besteht
zwar die Möglichkeit einen Backup-NameNode einzurichten
jedoch muss dieser beim Ausfall manuell eingebunden werden
[3].
•
B. Pig Latin
Mithilfe der Datenflusssprache Pig Latin lässt sich eine
Beschreibung angeben, wie Datensätze aus ein oder mehreren
verschiedener Quellen gelesen werden, wie diese bearbeitet
und dann wieder in ein oder mehrere Zielsysteme abgelegt
werden. Quell- und Zielsystem können z.B. Hadoop Cluster
oder lokale Dateien sein. Mit Pig Latin lassen sich ebenfalls standardisierte Operationen auf Daten wie zum Beispiel
Joins, Sortierungen, Filteroperationen etc. ausführen. Bei der
Entwicklung von Pig Latin wurde der Fokus auf folgende
Eigenschaften gelegt [4]:
• Einfache Programmierung
• Erweiterbarkeit
• Anfrageoptimierungsmöglichkeiten
Durch diese Eigenschaften ist es möglich eine komplexe sowie
effiziente Verarbeitung auf großen Datensätzen mit wenig
Aufwand zu realisieren. .
1) Abgrenzung von SQL: Bei SQL handelt es sich um eine
Anfragesprache, mit der sich Datenbankanfragen formulieren
lassen. Wird mit dem Anfrageergebnis weiter gearbeitet wird
die Anfrage schnell unübersichtlich, da temporäre Tabellen
erstellt werden müssen. Pig Latin hingegen ist eine datenflussbasierte Sprache in der Datenströme gelesen, verarbeitet und
ausgegeben werden ohne das eine Verwendung von Subqueries nötig ist. Dabei gilt zu bedenken, dass beide Sprachen
für verschiedene Umgebungen entwickelt wurden. SQL zeigt
seine Stärken, wenn es um Anfragen an konsistente relationale
Datenbankmanagementsysteme geht. Die Daten müssen dabei
einem Schema zugrunde liegen. Pig Latin hingegen ist dafür
ausgelegt auf einem Hadoop Cluster zu arbeiten, wo ein
Schema unbekannt oder inkonsistent sein kann [1].
C. Unterschiede zu MapReduce
Apache Pig erweitert das MapReduce Verfahren dementsprechend, dass eine einfachere, individuelle Umgebung bereitstellt wird. Dies bedeutet, dass bestimmte Funktionalitäten
mit Apache Pig deutlich schneller zu implementieren sind als
die Implementierung derselben Funktionalität mittels MapReduce und Java.
Pig stellt diesbezüglich einige komplexe Implementierungen
für Standartoperationen bereit. Dazukommend kann es durchaus vorkommen, dass die Daten im MapReduce-Verfahren
nicht gleichverteilt an den einzelnen Ressourcen im Hadoop
Cluster vorliegen. Dies kann dazu führen, dass einige Ressourcen deutlich mehr belastet werden als andere. Dies bedeutet
wiederrum, dass die Laufzeit sich entsprechend erhöht.
Apache Pig kann in einigen Fällen eine Gleichverteilung
durch die Operatoren Join und Order-by vornehmen. Ein
Weiterer Unterschied besteht darin, das MapReduce kein Dateitypensystem hat. Dadurch erhält der Benutzer zwar mehr
Freiheiten, dennoch wird ihm die Möglichkeit verwehrt, das
Codeanalysierungen automatisch erfolgen können. Pig ist in
der Lage den Code sowie den Datenfluss zu analysieren und
so den Benutzer früh auf Fehler hinzuweisen. Liegen jedoch
extrem hohe Performanceanforderungen vor sollte auf eine
reine MapReduce Lösung zurückgegriffen werden[1].
D. Anwendungsumgebungen
Apache Pig lässt sich in verschiedenen Anwendungsumgebungen ausführen [1]. Die einzelnen Umgebungen werden im
Folgenden kurz erläutert.
1) Lokaler Modus: Im lokalen Modus kann Apache Pig
auf einen einzelnen Rechner ausgeführt werden. Dazu werden
Daten aus einer oder mehreren bestehenden Dateien gelesen,
verarbeitet und in eine oder mehrere lokale Dateien geschrieben. Der lokale Modus eignet sich in erster Linie dazu, ein
implementiertes Pig Latin Skript zu debuggen oder einen
Prototypen auf kleinen Datenmengen zu testen, bevor dieses
im Hadopp Cluster auf großen Datenmengen angewandt wird.
2) Pig
im
Hadoop
Cluster:
Die
gängigste
Ausführungsvariante für Pig Latin Skripte ist das Hadoop
Cluster. Hierzu werden die auszuführenden Skripte von einem
Rechner aus in das vorhandene Hadoop Cluster importiert.
Dieser Rechner muss Zugriff auf das Cluster haben. Ebenfalls
muss der Name des Hadoop Koordinators (NameNode) und
der MapReduce-Koordinator (JobTracker) bekannt gemacht
werden.
3) Pig in der Cloud: Eine weitere Möglichkeit Pig zu
nutzen ist die Ausführung in der Cloud. Hierzu kann zum
Beispiel Amazons Web-Service Amazon Elastic MapReduce
(EMR) verwendet werden. EMR stellt ein Hadoop Cluster mit
einer gewünschten Kapazität bereit um datenintensive Berechnungen parallel durchzuführen. Die häufigsten Einsatzgebiete
sind unter anderen Webindizierung, Data-Mining, Protokolldatenanalyse, maschinelles Lernen sowie wissenschaftliche
Simulationen [5].
3
II. A PACHE P IG IN DER P RAXIS
Im Nachfolgenden Teil wird näher auf Apache Pig eingegangen. Dazu wird als erstes das zugrundeliegende Datenmodell von Apache Pig vorgestellt. Im Anschluss werden
Beispielhaft einige Sprachelemente von Pig Latin vorgestellt.
Diesbezüglich wird darauf eingegangen wie Daten eingelesen
verarbeitet und ausgeschrieben werden. Das darauf folgende
Thema beschäftigt sich mit der Verifikation von Pig Latin
Skripten und zeigt die grundlegenden Testmöglichkeiten. Ein
weiterer Punkt dieses Kapitels deutet an, worauf bei der
Entwicklung in puncto Performance geachtet werden sollte.
Zum Abschluss werden Benchmarks zu Pig betrachtet.
A. Pig´s Datenmodel
In Apache Pig existieren verschiedene Datentypen, welche
sich in zwei Typen Kategorisieren lassen.
• Einfache Datentypen (Scalar Types)
• Komplexe Datentypen (Complex Types)
1) Einfache Datentypen: Einfache Datentypen in Pig sind
Typen, die auch in den meisten Programmiersprachen vorkommen. Folgende sechs einfache Datentypen stehen zur
Verfügung [6].
• int: Vorzeichenbehaftete 32-Bit Integerzahl
• long: Vorzeichenbehaftete 64-Bit Integerzahl
• float: 32-Bit Fließkommazahl
• double: 64-Bit Fließkommazahl
• chararray: char Array (String) im Unicode UTF-8 Format
• Bytearray: Ein Array mit Bytes
2) Komplexe Datentypen: Komplexe Datentypen stellen in
Apache Pig Container dar. Diese können wiederrum komplexe
oder einfache Datentypen enthalten. Folgende drei Containertypen stehen zur Verfügung [6].
• Map: Eine Map stellt in Pig eine Menge von Key Value
paaren als Bytearray dar, wobei der Schlüssel die Position
angibt. Der Wert kann jeweils ein beliebiger Pig Datentyp
sein.
• Tuple: Ein Tupel ist eine geordnete Menge mit einer
festen Anzahl von Werten. Übertragen auf Datenbanken
könnte ein Tupel eine Zeile in einer Tabelle darstellen.
Die einzelnen Positionen der geordneten Menge lassen sich namentlich referenzieren, sodass eine einfache
Handhabung möglich ist. Ebenfalls ist es möglich ein
Tupelschema zu definieren
• Bag: Dieser Datentyp ist eine ungeordnete Menge von
Tupeln. Bags lassen sich wie Tupel ebenfalls in einen
Schema definieren, sodass alle Tupel innerhalb des Bags
genauer beschrieben werden können.
B. User Defined Funktions (UDFs)
Apache Pig ermöglicht es innerhalb des Pig Latin Skript
benutzerdefinierte Funktionen (UDFs) zu nutzen. Pig stellt
eine Reihe von eingebauten Funktionen für die Nutzung mathematischer und datentypbasierter Operationen bereit [7]. Des
Weiteren können eigene UDFs in Java implementiert und in
Latin Pig genutzt werden [8].
C. Die Sprachelemente von Pig Latin
In den folgenden Abschnitten werden die grundlegenden
Sprachelemente von Pig Latin vorgestellt um die grundlegende Struktur zu verdeutlichen. Eine Auflistung aller vorhandenen Sprachelemente ist der Apache Pig Dokumentation
[9] zu entnehmen. Zu bedenken sei, dass Variablennamen
und UDF-Funktionen Case-sensitive sind. Schlüsselwörter hingegen sind nicht Case-sensitiv. Zur Verdeutlichung werden
Schlüsselwörter in den nachfolgenden Beispielen groß geschrieben.
1) Kommentare: Kommentare können in Pig Latin gangzeilig oder über mehrere Zeilen angelegt werden. Zwei Operatoren stehen diesbezüglich bereit.
•
•
Einzeiliger Kommentar (- - Kommentar) im SQL-Stil.
Mehrzeiliger Kommentar (/ * Kommentar * /) im JavaStil.
2) Daten lesen / schreiben: Für das Lesen von Daten
aus einer Datei und für das Schreiben von Daten in eine
Datei kommen bei Apache Pig verschiedene load und store
Funktionen zum Einsatz, welche jeweils für einen bestimmten Bereich geeignet sind. So lässt sich zum Beispiel die
Load/Store-Funktion ”PigStorage”nutzen um mit Daten aus
einem Hadoop-Cluster zu arbeiten. Ein weiteres Beispiel ist
die Funktion ”HBaseStorage”[10], welche Daten aus einer
Apache HBase [11] lädt. An dieser Stelle sei noch gesagt, das
eine individuelle Nutzung durch die Implementierung eigener
Load- und Storefunktionen möglich ist [12].
Um aus einer Datei Daten zu importieren wird der Befehl load
benötigt.
a = LOAD ’/data/dataInputFile’;
Das Beispiel lädt den Inhalt der Datei ”dataInputFileäus
dem Ordner ”dataëin und hinterlegt die Daten in die Variable
ä”. Dabei müssen die Daten in diesen Fall Tab-separiert
vorliegen. Andere Separatoren können durch explizites Angeben der Standard-Loadfunktion PigStorage() innerhalb der
Übergabeparameter spezifiziert werden. Das folgende Beispiel
liest Daten ein, die durch ein Komma getrennt sind.
a = LOAD ’/data/dataInputFile’ USING PigStorage(’,’)
;
Ebenfalls lassen sich Schemata mittels des AS“ angeben.
”
Diese vereinfachen den späteren Umgang mit den Daten indem
sie eine Referenz auf die jeweiligen Felder des Datensatzes
bereitstellen.
users = LOAD ’/data/userlist’ AS (loginname, eMail,
birthday);
Für das Exportieren von Daten in eine Datei wird der Befehl
ßtore”benötigt.
STORE users INTO ’/data/dataOutputFile’ USING
PigStorage(’,’);
Die Angabe der Store-Funktion ist hier ebenfalls optional und kann äquivalent durch eine beliebige andere StoreFunktion ersetzt werden.
4
3) Relationale Operationen: Zwischen dem Lesen und
Schreiben von Daten kommen relationale Operationen zum
Einsatz. Diese bietet verschiedenste Möglichkeiten Daten umzuformen oder zu vereinigen. Im Folgenden werden beispielhaft einige essentielle Operation vorgestellt. Für weitere
Informationen diesbezüglich und eine Auflistung aller vorhandenen Operationen sei auf den entsprechenden Teil der
Dokumentation [13] verwiesen.
FOREACH: Der foreach-Befehl ermöglicht es alle Datensätze,
die in einer Variable hinterlegt sind, zu durchlaufen um gewisse datenbasierte Operationen oder UDFs auf einem Cluster von
Daten gleicher Struktur anzuwenden. Das nachfolgende Beispiel wählt aus den Datensätzen der Variable users“ jeweils
”
die ersten beiden Felder aus und legt das Ergebnis in result“
”
ab.
users = LOAD ’/data/userlist’ AS (loginName, eMail,
birthday);
result = FOREACH users GENERATE loginName, eMail;
--pigunit.pig
divs = LOAD ’NYSE_dividends’ AS (exchange, symbol,
date, dividends);
grpd = GROUP divs ALL
avgdiv = FOREACH grpd GENERATE AVG(divs.dividends);
STORE avgdiv INTO ’average_dividend’;
Das folgende Beispiel zeigt einen Test für das Skript aus
der Datei ”pigunit.pig”. Im ersten Schritt des Tests wird
eine Variable vom Typ ”PigTest”[15] angelegt, wobei im
Konstruktor die Skriptdatei übergeben wird. Als nächstes wird
das gewünschte Ergebnis unter Angabe des richtigen Datentyps angegeben. Die Funktion “assertOutput()“ der Klasse
”PigTest”prüft im Anschluss ob das gewünschte Ergebnis mit
dem berechneten Ergebnis übereinstimmt. Der String ävgdiv”referenziert dabei auf die gleichnamige Variable im Skript.
public class PigUnitExample {
private PigTest test;
private static Cluster cluster;
@Test
public void testDataInFile() throws
ParseException, IOException {
FILTER: Der Filteroperator ist in de Lage ein bestimmtes Datum aus einem Satz von Datensäten nach bestimmten Regeln
zu Filtern. Diese Regeln können vom Benutzer angegeben werden und können aus Vergleichen oder regulären Ausdrücken
bestehen.
users = LOAD /data/userlist’ AS (loginName, eMail);
startsWithM = FILTER users BY loginName matches ’M
.*’;
Das angegebene Beispiel wählt aus den Datensätzen in users“
”
alle heraus, bei denen der Loginname mit M“ beginnt und legt
”
diese in der Variable startsWithM“ ab.
”
GROUP: Der Group-Operation gruppiert Datensätze nach
einen definierten Datum. Die Gruppierten Daten werden dann
jeweils in einem Container vom Typ Bag“ abgelegt. Group
”
unterscheidet sich vom SQL Befehl GROUP-BY dahingehend das bei Pig keine Aggregationsfunktion in Verbindung
zu GROUP stehen muss. Das heißt, dass die Daten nicht
reduziert werden müssen. Das nachfolgende Beispiel gruppiert
die Kundenliste aus der Variable customers“ nach dem Wert
”
zipcode“ und legt diese in result“ ab. Das Ergebnis ist eine
”
”
Bag“. Diese Bag“ enthält wiederum Bags“ welche jeweils
”
”
”
Daten mit dem gleichen Wert für zipcode“ haben.
”
customers = LOAD /data/customerList’ AS (name,
zipcode,...);
result = GROUP customers BY zipcode;
test = new PigTest("../pigunit.pig")
;
String[] output = { "
(0.27305267014925455)" };
test.assertOutput("avgdiv", output);
}
}
Dadurch, dass Variablenwerte getestet werden, bietet die
Klasse ”PigTest“ die Möglichkeit Zwischenergebnisse im
Skript zu validieren um nach Fehlerquellen zu suchen.
Statt externe Daten zu verwenden können die Testdaten auch
innerhalb des Tests angegeben werden. Dies ist sinnvoll wenn
die realen Daten zum Testzeitpunkt nicht vorliegen oder zu
groß sind. Die Angabe der Testdaten erfolgt dann innerhalb
der Testmethode.
String[] input = {
"NYSE\tCPO\t2009-12-30\t0.14",
"NYSE\tCPO\t2009-01-06\t0.14",
"NYSE\tCCS\t2009-10-28\t0.414",
"NYSE\tCCS\t2009-01-28\t0.414",
"NYSE\tCIF\t2009-12-09\t0.029",
};
Damit die angegebenen Testdaten verwendet werden
können, müssen diese in der Methode “assertOutput()“ angegeben werden.
test.assertOutput("divs", input, "avgdiv", output);
D. Testen
Apache Pig bietet seit der Version 0.8 das Framework
PigUnit [14] zum Testen von Pig Latin Skripten an. Das Framework integriert Testmöglichkeiten für Pig Latin-Skripte in
JUnit. Neben dem regulären Testen kann mittels PigUnit auch
sichergestellt werden, das nach Änderungen an UDFs oder
Versionsänderungen von Hadoop bzw. Pig die gewünschte
Funktionalität nach wie vor gegeben ist.
Für die nachfolgenden Beispiele aus [1] wird folgendes Pig
Latin-Skript [1] angenommen, welches einen Durchschnittswert berechnet und in der Variable ävgdivı̈nnerhalb des Skripts
ablegt.
Durch Angabe der ersten beiden Parameter wird die Funktion ”load“ für die Skriptvariable divs überschrieben, sodass
der Inhalt des String-Arrays input als Eingabestrom verwendet
wird. Auf die gleiche Weise lässt ich das zu verwendende
Pig Latin-Skript innerhalb des Tests angeben. Dazu wird
wiederrum ein Stringarray mit den Inhalten des Skripts erstellt.
String[] script = {
"divs = LOAD ’../../..data/NYSE_dividends’
AS (exchange, symbol,...,);",
"grpd = GROUP divs ALL;",
"avgdiv = FOREACH grpd GENERATE AVG(divs.
dividends);",
"STORE avgdiv INTO ’average_dividends’;".
};
5
Durch Angabe des Stringarrays als Übergabeparameter für
das Objekt vom Typ “PigTest“ lässt sich das erstellte Skript
verwenden.
test = new PigTest(script);
E. Performance
Wie auch in anderen Sprachen ist die Performance des
erstellten Codes von einigen Faktoren abhängig, welche es zu
beachten gilt. So auch bei Pig. Für die Implementierung eines
performanten Pig Latin-Skripts stellt Apache einige Regeln
zur Verfügung [16]. Um einen Eindruck diesbezüglich zu
vermitteln werden im Folgenden einige dieser Regeln erläutert.
1) Der richtige Datentyp: Pig schreibt keine explizite Datentypdefinition vor. Dennoch ist es aus Performancegründen
an einigen Stellen sinnvoll den passenden Datentyp explizit
mit anzugeben. Liegen Daten zum Beispiel typisiert in einen
Bytearray vor werden diese für numerische Operationen automatisch als Doublewerte behandelt. Bei folgender beispielhafter UDF werden jedoch Werte des Typs Integer summiert.
long SUM({(int)} input)
In diesem Beispiel entstehen, ohne explizite Datentypeingabe, Performancekosten die leicht hätten eingespart werden
können.
2) Auswahl der join-Operation: Wie auch in anderen Bereichen der Anfrageoptimierung kann sich die Auswahl des
passenden Join-Operation signifikant auf die Performance auswirken. Abb.3 gibt einen ersten Leitfaden für die Auswahl
von Join-Operationen an die Hand. Dabei ist Faktoren wie
Speicherplatz und Sortierungsgegebenheiten von Bedeutung.
Zeitpunkt
23.02.2009
28.05.2009
28.06.2009
27.08.2009
18.10.2009
04.01.2010
29.05.2010
11.06.2011
Geschwindigkeitsfaktor
1,97
1,83
1,68
1,53
1,04
1,09
1,15
1,16
Testmethode
PigMix
PigMix
PigMix
PigMix
PigMix
PigMix
PigMix2
PigMix2
Tabelle I: Entwicklung von Pig hinsichtlich der Laufzeiten
werden um irrelevante Teildaten zeitnah aus den Datenströmen
entfernen zu lassen.
F. Benchmarks zu Apache Pig
PigMix und PigMix2 sind jeweils eine Menge von Queries,
welche eingesetzt werden um auf den neusten Releaseversionen Benchmarks durchzuführen. PigMix2 beinhaltet neben
zusätzlichen Queries alle Queries von PigMix. Das Ziel von
dabei ist es die Skalierbarkeit sowie die benötigte Zeit für
die Ausführung verschiedener Queries zwischen Apache Pig
und einer reinen MapReduce Implementierung in Java zu
vergleichen.
Die auf Hadoop basierte Testumgebung umfasste dabei 26
Worker und ein NameNode auf dem ebenfalls der JobTracker läuft. Als grundlegendes Ergebnis zeigte sich, dass eine
reine Java Implementierung nach wie vor in den meisten
Fällen die schneller Variante ist. Dazu sei zu bedenken,
dass der Entwicklungsaufwand hier jedoch wesentlich höher
ausfällt. Die zeitliche Tendenz für die einzelnen Releases
zeigt, dass sich die Laufzeiten von Pig gegenüber der reinen
Java-Implementierung deutlich verbessert haben, sodass sich
die Laufzeiten an die reinen Java-Implementierungslaufzeiten
angenähert haben.
Tabelle I zeigt den mittleren Vergleich über die einzelnen Releases von Pig im Vergleich zu einer reinen JavaImplementierung. Der Faktor gibt dabei den Durschnitt aller
Quotienten des Verhältnisses Java / Pig an. Tabelle II zeigt
die Laufzeiten verschiedener Operationen und das Verhältnis
zwischen Pig und einer Java-Implementierung. Für weitere
Informationen bezüglich PigMix sei auf die offizielle Website
von PigMix verwiesen [17].
III. Z USAMMENFASSUNG
Abbildung 3: Auswahl des optimalen Join-Operators [1]
3) Filter und Projektion: Pig nutzt intern einen logischen
Optimierer der dafür zuständig ist Filter und Projektionen
im Skript möglichst früh auszuführen. Dennoch sollte diese
beiden Operatoren so früh und oft wie möglich eingesetzt
Mit dem Subsystem Apache Pig aus dem Hadoop Framework lassen sich viele Daten schnell, einfach und zuverlässig
abfragen. Pig nutzt zwei weiter Subsysteme des Hadoop
Framework. Zum Einen das verteilte Dateisystem HDFS und
zum Anderen Hadoops MapReduce-Verfahren mit dem Anfragen verteilt ausgeführt werden können. Die Daten müssen
dabei nicht in einem geordneten Schema, wie in relationalen
Datenbanken, vorliegen.
Mit Hilfe der Anfragesprache Pig Latin lässt sich mit vergleichsmäßig wenig Aufwand eine komplexe Datenbankanfrage modellieren. Dazu werden immer die drei Schritte einlesen, verarbeiten und ausgeben berücksichtigt. Innerhalb des
Schrittes Daten verarbeiten“ lassen sich benutzerdefinierte
”
6
Querie
L1 explode
L2 fr join
L3 join
L4 distinct agg
L5 anti-join
L6 large group by key
L7 nested split
L8 group all
L9 order by 1 field
L10 order by multi. fields
L11 distinct + union
L12 multi-store
L13 outer join
L14 merge join
L15 multi. diff. aggregates
L16 accumulative mode
L17 wide key group
Java
139
48.67
107.33
78.33
114
74.33
77.33
57
280.33
354.67
141
187.33
44.33
111.67
87
75.33
152.33
Pig
130
66
138
106
135.67
103.67
77.67
56.33
384.67
380
164
109.67
78
105.33
89.67
87.67
171.33
Verhältnis Java/Pig
0.94
1.36
1.29
1.35
1.19
1.39
1.00
0.99
1.37
1.07
1.16
0.59
1.76
0.94
1.03
1.16
1.12
Tabelle II: Ausführungszeiten von PigMix2
Funktionen (UDFs) aufrufen. Eine Reihe mathematischer und
datentypoperativer UDFs stehen hierbei zur Verfügung. Ebenso lassen sich eigene UDFs in Java definieren und im Pig Latin
verwenden.
Durch das Datenmodell von Pig ist es möglich eine Codeanalyse automatisch vornehmen zu lassen. Dies bedeutet,
dass z.B. geprüft wird ob die verwendeten Datentypen an
den jeweiligen Positionen sinnvoll sind. Jedoch ist es dem
Anwender überlassen, ob dieser Angaben zu den Datentypen
innerhalb des Skripts macht.
Neben der automatischen Codeanalyse bietet es sich
an zusätzlich PigUnit zu verwenden. PigUnit bietet die
Möglichkeit Pig Latin-Skripte zu testen. Dabei setzt PigUnit
auf JUnit auf, wodurch eine komfortable Testumgebung zur
Verfügung steht.
Damit die Performance von Pig erhalten bleibt, sind einige
Dinge bei der Implementierung der Skripte zu beachten. Die
meisten davon beziehen sich auf Datenoperationen und lassen
sich ebenfalls im Anfrageoptimierungsbereich wiederfinden.
Apache Pig bietet dem Benutzer eine einfach zu verstehende
Datenflusssprache Pig Latin. Zwar können die Anfragen auch
ohne Apache Pig modeliert weden, jedoch beansprucht dies in
einigen Fällen deutlich mehr Aufwand. PigMix Benchmarks
haben gezeigt, das die Ausführungsgeschwindigkeit, seit dem
ersten Release von Pig, deutlich gestiegen ist. Jedoch ist die
durchschnittliche Ausführungsgeschwindigkeit von Pig Skripten gegenüber einer reinen Java Implementierung immer noch
leicht höher.
L ITERATUR
[1] A. Gates, Programming Pig, first edition ed. OREILLY, 2011.
[2] [Online]. Available: http://hadoop.apache.org
[3] T. White, Hadoop: The Definitive Guide, F. Edition, Ed. OREILLY,
2009.
[4] [Online]. Available: http://pig.apache.org
[5] [Online]. Available: http://aws.amazon.com/de/elasticmapreduce/
[6] [Online]. Available: http://pig.apache.org/docs/r0.7.0/piglatin ref2.html#
Data+Types+and+More
[7] A. Gates, Programming Pig, first edition ed. OREILLY, 2011, p.
Appendix A. [Online]. Available: ]http://pig.apache.org/docs/r0.9.1/udf.
html
[8] [Online]. Available: http://pig.apache.org/docs/r0.9.1/udf.html
[9] [Online]. Available: http://pig.apache.org/docs/r0.10.0/basic.html
[10] [Online]. Available: http://pig.apache.org/docs/r0.9.1/api/org/apache/pig/
backend/hadoop/hbase/HBaseStorage.html
[11] [Online]. Available: http://hbase.apache.org
[12] [Online]. Available: http://pig.apache.org/docs/r0.8.1/udf.html#Load%
2FStore+Functions
[13] [Online].
Available:
http://pig.apache.org/docs/r0.10.0/basic.html#
Relational+Operators
[14] [Online]. Available: http://pig.apache.org/docs/r0.8.1/pigunit.html
[15] [Online]. Available: ]http://javasourcecode.org/html/open-source/pig/
pig-0.8.1/org/apache/pig/pigunit/PigTest.html
[16] [Online].
Available:
http://pig.apache.org/docs/r0.9.1/perf.html#
optimization-rules
[17] [Online]. Available: https://cwiki.apache.org/confluence/display/PIG/
PigMix
Herunterladen