Apache Pig UDF: Del 1 - Funktioner för utvärdering, aggregering och filter



Detta inlägg beskriver om Apache Pig UDF - Eval, Aggregate & Filter Functions. Ta en titt på funktionerna Eval, Aggregate & Filter.

Apache Pig erbjuder omfattande stöd för användardefinierade funktioner (UDF) som ett sätt att specificera anpassad bearbetning. Gris UDF kan för närvarande köras på tre språk: Java, Python, JavaScript och Ruby. Det mest omfattande stödet ges för Java-funktioner.





Java UDF: er kan åberopas på flera sätt. Den enklaste UDF kan bara utvidga EvalFunc, vilket bara kräver att exec-funktionen ska implementeras. Varje Eval UDF måste implementera detta. Dessutom, om en funktion är algebraisk kan den implementera algebraiskt gränssnitt för att avsevärt förbättra frågan.

Betydelsen av UDF i gris:

Pig tillåter användare att kombinera befintliga operatörer med sin egen eller andras kod via UDF. Fördelen med Pig är dess förmåga att låta användare kombinera sina operatörer med sin egen eller andras kod via UDF. Upp till version 0.7 måste alla UDF-filer vara skrivna i Java och implementeras som Java-klasser. Detta gör det lättare att lägga till nya UDF: er till Pig genom att skriva en Java-klass och informera Pig om JAR-filen.



Grisen själv kommer med några UDF. Före version 0.8 var det en mycket begränsad uppsättning med endast standard SQL-aggregerade funktioner och några andra. I 0,8 tillsattes ett stort antal standardsträngbearbetning, matematik och komplexa UDF: er.

Vad är en spargris?

Piggybank är en samling användardrivna UDF: er som släpps tillsammans med Pig. Piggybank UDF: er ingår inte i Pig JAR, så du måste registrera dem manuellt i ditt skript. Du kan också skriva dina egna UDF: er eller använda dem som skrivits av andra användare.

Eval-funktioner

UDF-klassen utvidgar EvalFunc-klassen som är basen för alla Eval-funktioner. Alla utvärderingsfunktioner utökar Java-klassen 'org.apache.pig.EvalFunc. ”Det parametreras med returtypen för UDF som i detta fall är en Java-sträng. Kärnmetoden i denna klass är ”exec.” Den första raden i koden indikerar att funktionen är en del av myudfs-paketet.



Det tar en post och returnerar ett resultat som kommer att åberopas för varje post som passerar genom exekveringsrörledningen. Det tar en tuple, som innehåller alla fälten som skriptet skickar till din UDF som inmatning. Den returnerar sedan den typ som du har parametrerat EvalFunc med.

Denna funktion åberopas för varje ingångstuple. Inmatningen i funktionen är en tupel med inmatningsparametrar i den ordning de skickas till funktionen i grisskriptet. I exemplet som visas nedan tar funktionen sträng som inmatning. Följande funktion konverterar strängen från gemener till versaler. Nu när funktionen är implementerad måste den kompileras och inkluderas i en JAR.

paket myudfs importera java.io.IOException importera org.apache.pig.EvalFunc importera org.apache.pig.data.Tuple allmän klass UPPER förlänger EvalFunc {public String exec (Tuple input) kastar IOException {if (input == null || input.size () == 0) returnera null försök {String str = (String) input.get (0) return str.toUpperCase ()} catch (Exception e) {throw new IOException ('Fångat undantags bearbetning input rad', e)}}}

Aggregerade funktioner:

Aggregerade funktioner är en annan vanlig typ av Eval-funktion. Aggregerade funktioner tillämpas vanligtvis på grupperade data. Funktionen Aggregate tar en påse och returnerar ett skalärt värde. En intressant och värdefull egenskap hos många aggregerade funktioner är att de kan beräknas stegvis på ett distribuerat sätt. I Hadoop-världen betyder detta att de partiella beräkningarna kan göras av Map och Combiner och det slutliga resultatet kan beräknas av Reducer.

Det är mycket viktigt att se till att aggregerade funktioner som är algebraiska implementeras som sådana. Exempel på denna typ inkluderar de inbyggda COUNT, MIN, MAX och AVERAGE.

mvc-arkitektur i java med diagram

RÄKNA är ett exempel på en algebraisk funktion där vi kan räkna antalet element i en delmängd av data och sedan summera räkningarna för att producera en slutlig utgång. Låt oss titta på implementeringen av COUNT-funktionen:

public class COUNT utvidgar EvalFunc implementerar Algebraic {public Long exec (Tuple input) kastar IOException {return count (input)} public String getInitial () {return Initial.class.getName ()} public String getIntermed () {return Intermed.class. getName ()} public String getFinal () {return Final.class.getName ()} statisk public class Initial utvidgar EvalFunc {public Tuple exec (Tuple input) kastar IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} statisk allmän klass Intermed utökar EvalFunc {public Tuple exec (Tuple input) kastar IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} static public class Slutlig utvidgar EvalFunc {public Tuple exec (Tuple input) kastar IOException {retur summa (input)}} statisk skyddad Lång räkning (Tuple input) kastar ExecException {Object värden = input.get (0) om (värden instans av DataBag) returnerar ((DataBag) värden) .storlek () annars om (värden instans av karta) returnerar nya långa (((karta) värden) .storlek ())} statisk skyddad lång summa (Tuple i nput) kastar ExecException, NumberFormatException {DataBag-värden = (DataBag) input.get (0) lång summa = 0 för (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) sum + = (Long) t.get (0)} retursumma}}

COUNT implementerar algebraiskt gränssnitt som ser ut så här:

offentligt gränssnitt Algebraic {public String getInitial () public String getIntermed () public String getFinal ()}

För att en funktion ska vara algebraisk måste den implementera algebraiskt gränssnitt som består av definition av tre klasser härledda från EvalFunc. Kontraktet är att exekveringen av Initial-klassen anropas en gång och skickas till den ursprungliga ingångstupeln. Dess produktion är en tupel som innehåller partiella resultat. Interec-klassens exec-funktion kan kallas noll eller flera gånger och tar som inmatning en tuple som innehåller partiella resultat producerade av den initiala klassen eller genom tidigare anrop av Intermed-klassen och producerar en tuple med ett annat delresultat. Slutligen kallas exec-funktionen för Final-klassen och ger slutresultatet som en skalartyp.

Filterfunktioner:

Filterfunktioner är utvärderingsfunktioner som returnerar ett booleskt värde. Det kan användas var som helst ett booleskt uttryck är lämpligt, inklusive FILTER-operatören eller Bincond-uttrycket. Apache Pig stöder inte Boolean helt, så filterfunktioner kan inte visas i uttalanden som ”Foreach”, där resultaten skickas till en annan operatör. Filterfunktioner kan dock användas i filteruttalanden.

I exemplet nedan implementeras IsEmpty-funktionen:

importera java.io.IOException importera java.util.Map importera org.apache.pig.FilterFunc importera org.apache.pig.PigException importera org.apache.pig.backend.executionengine.ExecException importera org.apache.pig.data.DataBag import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * Bestäm om en påse eller karta är tom. * / public class IsEmpty utvidgar FilterFunc {@Override public Boolean exec (Tuple input) kastar IOException {try {Object värden = input.get (0) om (värden instans av DataBag) returnerar ((DataBag) värden) .storlek () == 0 annat om (värden instans av karta) returnerar ((karta) värden) .storlek () == 0 annat {int errCode = 2102 Sträng msg = 'Kan inte testa ett' + DataType.findTypeName (värden) + 'för tomhet.' kasta ny ExecException (msg, errCode, PigException.BUG)}} fångst (ExecException ee) {kasta ee}}}