Inleiding tot Apache Beam

1. Overzicht

In deze tutorial introduceren we Apache Beam en verkennen we de fundamentele concepten.

We beginnen met het demonstreren van de use case en voordelen van het gebruik van Apache Beam, en daarna behandelen we fundamentele concepten en terminologieën. Daarna zullen we een eenvoudig voorbeeld doorlopen dat alle belangrijke aspecten van Apache Beam illustreert.

2. Wat is Apache Beam?

Apache Beam (Batch + strEAM) is een uniform programmeermodel voor batch- en streaminggegevensverwerkingstaken. Het biedt een softwareontwikkelingskit om gegevensverwerkingspijplijnen te definiëren en te construeren, evenals hardlopers om ze uit te voeren.

Apache Beam is ontworpen om een ​​draagbare programmeerlaag te bieden. In feite vertalen de Beam Pipeline Runners de gegevensverwerkingspijplijn naar de API die compatibel is met de backend naar keuze van de gebruiker. Momenteel worden deze gedistribueerde verwerkingsbackends ondersteund:

  • Apache Apex
  • Apache Flink
  • Apache Gearpump (incuberen)
  • Apache Samza
  • Apache Spark
  • Google Cloud Dataflow
  • Hazelcast Jet

3. Waarom Apache Beam?

Apache Beam combineert batch- en streaminggegevensverwerking, terwijl anderen dit vaak doen via afzonderlijke API's. Bijgevolg is het heel gemakkelijk om een ​​streamingproces te veranderen in een batchproces en vice versa, bijvoorbeeld als de vereisten veranderen.

Apache Beam verhoogt de draagbaarheid en flexibiliteit. We concentreren ons op onze logica in plaats van op de onderliggende details. Bovendien kunnen we de backend van de gegevensverwerking op elk moment wijzigen.

Er zijn Java-, Python-, Go- en Scala-SDK's beschikbaar voor Apache Beam. Inderdaad, iedereen in het team kan het gebruiken met de taal van hun keuze.

4. Fundamentele concepten

Met Apache Beam kunnen we workflow-grafieken (pijplijnen) construeren en uitvoeren. De belangrijkste concepten in het programmeermodel zijn:

  • PCollection - staat voor een dataset die een vaste batch of een datastroom kan zijn
  • PTransform - een gegevensverwerking die een of meer PCollections en voert nul of meer uit PCollections
  • Pijpleiding - vertegenwoordigt een gerichte acyclische grafiek van PCollection en PTransform, en omvat dus de volledige gegevensverwerkingstaak
  • PipelineRunner - voert een Pijpleiding op een gespecificeerde gedistribueerde verwerkingsbackend

Simpel gezegd, een PipelineRunner voert een Pijpleiding, en een Pijpleiding bestaat uit PCollection en PTransform.

5. Voorbeeld van het aantal woorden

Nu we de basisconcepten van Apache Beam hebben geleerd, gaan we een taak voor het tellen van woorden ontwerpen en testen.

5.1. Een balkpijpleiding aanleggen

Het ontwerpen van de workflow-grafiek is de eerste stap in elke Apache Beam-taak. Laten we de stappen van een taak voor het tellen van woorden definiëren:

  1. Lees de tekst uit een bron.
  2. Splits de tekst in een lijst met woorden.
  3. Alle woorden in kleine letters.
  4. Snijd leestekens bij.
  5. Filter stopwoorden.
  6. Tel elk uniek woord.

Om dit te bereiken, moeten we de bovenstaande stappen omzetten in één Pijpleiding gebruik makend van PCollection en PTransform abstracties.

5.2. Afhankelijkheden

Voordat we onze workflow-grafiek kunnen implementeren, moeten we de kernafhankelijkheid van Apache Beam aan ons project toevoegen:

 org.apache.beam beam-sdks-java-core $ {beam.version} 

Beam Pipeline Runners vertrouwen op een gedistribueerde verwerkingsbackend om taken uit te voeren. Laten we toevoegen DirectRunner als een runtime-afhankelijkheid:

 org.apache.beam beam-runners-direct-java $ {beam.version} looptijd 

In tegenstelling tot andere Pipeline Runners, DirectRunner heeft geen extra installatie nodig, waardoor het een goede keuze is voor starters.

5.3. Implementatie

Apache Beam maakt gebruik van het Map-Reduce-programmeerparadigma (hetzelfde als Java Streams). In feite is het een goed idee om een ​​basisconcept te hebben van verminderen(), filter(), tellen (), kaart(), en flatMap () voordat we verder gaan.

Een Pijpleiding is het eerste wat we doen:

PipelineOptions opties = PipelineOptionsFactory.create (); Pipeline p = Pipeline.create (opties);

Nu passen we onze taak voor het tellen van woorden in zes stappen toe:

PCollection wordCount = p .apply ("(1) Lees alle regels", TextIO.read (). van (inputFilePath)) .apply ("(2) Flatmap naar een lijst met woorden", FlatMapElements.into (TypeDescriptors.strings () ) .via (line -> Arrays.asList (line.split ("\ s")))) .apply ("(3) Alles in kleine letters", MapElements.into (TypeDescriptors.strings ()) .via (word - > word.toLowerCase ())) .apply ("(4) Trim interpuncties", MapElements.into (TypeDescriptors.strings ()) .via (word -> trim (word))) .apply ("(5) Filter stopwoorden ", Filter.by (woord ->! IsStopWord (woord))) .apply (" (6) Tel woorden ", Count.perElement ());

Het eerste (optionele) argument van van toepassing zijn() is een Draad dat is alleen voor een betere leesbaarheid van de code. Hier is wat elk van toepassing zijn() doet in de bovenstaande code:

  1. Eerst lezen we regel voor regel een invoertekstbestand met TextIO.
  2. We splitsen elke regel op door spaties en brengen deze plat in een lijst met woorden.
  3. Het aantal woorden is niet hoofdlettergevoelig, dus we zetten alle woorden in kleine letters.
  4. Eerder splitsten we regels op met witruimte, en eindigden we met woorden als 'woord!' en "woord?", dus verwijderen we leestekens.
  5. Stopwoorden zoals "is" en "door" komen vaak voor in bijna elke Engelse tekst, dus we verwijderen ze.
  6. Ten slotte tellen we unieke woorden met behulp van de ingebouwde functie Count.perElement ().

Zoals eerder vermeld, worden pijplijnen verwerkt op een gedistribueerde backend. Het is niet mogelijk om een PCollection in-memory omdat het is verdeeld over meerdere backends. In plaats daarvan schrijven we de resultaten naar een externe database of bestand.

Eerst converteren we onze PCollection naar Draad. Vervolgens gebruiken we TextIO om de uitvoer te schrijven:

wordCount.apply (MapElements.into (TypeDescriptors.strings ()) .via (count -> count.getKey () + "->" + count.getValue ())) .apply (TextIO.write (). to ( outputFilePath));

Nu dat onze Pijpleiding definitie is voltooid, we kunnen het uitvoeren en testen.

5.4. Hardlopen en testen

Tot nu toe hebben we een Pijpleiding voor de taak om het aantal woorden te tellen. Laten we nu het Pijpleiding:

p.run (). waitUntilFinish ();

Op deze regel code stuurt Apache Beam onze taak naar meerdere DirectRunner gevallen. Als gevolg hiervan worden aan het einde verschillende uitvoerbestanden gegenereerd. Ze bevatten dingen als:

... apache -> 3 stralen -> 5 rotsen -> 2 ...

Het definiëren en uitvoeren van een gedistribueerde taak in Apache Beam is zo eenvoudig en expressief als dit. Ter vergelijking: implementatie van het aantal woorden is ook beschikbaar op Apache Spark, Apache Flink en Hazelcast Jet.

6. Waar gaan we heen?

We hebben met succes elk woord uit ons invoerbestand geteld, maar we hebben nog geen rapport met de meest voorkomende woorden. Zeker, het sorteren van een PCollection is een goed probleem om op te lossen als onze volgende stap.

Later kunnen we meer leren over Windowing, Triggers, Metrics en meer geavanceerde Transforms. Apache Beam-documentatie biedt diepgaande informatie en referentiemateriaal.

7. Conclusie

In deze tutorial hebben we geleerd wat Apache Beam is en waarom het de voorkeur heeft boven alternatieven. We hebben ook basisconcepten van Apache Beam gedemonstreerd met een voorbeeld van het aantal woorden.

De code voor deze tutorial is beschikbaar op GitHub.