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