DStreams vs. DataFrames: To varianter af Spark Streaming
Dette indlæg er en gæstepublikation skrevet af Yaroslav Tkachenko, softwarearkitekt hos Activision.
Apache Spark er en af de mest populære og kraftfulde rammer til databehandling i stor skala. Det blev skabt som et alternativ til Hadoops MapReduce-ramme til batcharbejdsbelastninger, men nu understøtter det også SQL, maskinlæring og stream processing. I dag vil jeg fokusere på Spark Streaming og vise nogle få muligheder, der er tilgængelige for stream processing.
Stream data processing bruges, når dynamiske data genereres kontinuerligt, og det findes ofte i big data use cases. I de fleste tilfælde behandles data i næsten realtid, en post ad gangen, og den indsigt, der er afledt af dataene, bruges også til at give advarsler, gengive dashboards og fodre maskinlæringsmodeller, der hurtigt kan reagere på nye tendenser i dataene.
DStreams vs. DataFrames
Spark Streaming gik alpha med Spark 0.7.0. Det er baseret på ideen om diskretiserede strømme eller DStreams. Hver DStream er repræsenteret som en sekvens af RDD’er, så det er let at bruge, hvis du kommer fra RDD-understøttede batch-arbejdsbelastninger på lavt niveau. DStreams gennemgik en masse forbedringer i løbet af denne periode, men der var stadig forskellige udfordringer, primært fordi det er et API på meget lavt niveau.
Som en løsning på disse udfordringer blev Spark Structured Streaming introduceret i Spark 2.0 (og blev stabil i 2.2) som en udvidelse bygget oven på Spark SQL. Derfor drager den fordel af Spark SQL-kode og hukommelsesoptimeringer. Structured Streaming giver også meget kraftfulde abstraktioner som Dataset/DataFrame API’er samt SQL. Du behøver ikke længere beskæftige dig direkte med RDD!
Både Structured Streaming og Streaming med DStreams bruger micro-batching. Den største forskel er latenstid og garantier for levering af meddelelser: Structured Streaming tilbyder præcis én gang levering med en latenstid på over 100 millisekunder, mens Streaming med DStreams-tilgangen kun garanterer mindst én gang levering, men kan give en latenstid på millisekunder.
Jeg foretrækker personligt Spark Structured Streaming til enkle anvendelsestilfælde, men Spark Streaming med DStreams er virkelig god til mere komplicerede topologier på grund af dens fleksibilitet. Derfor vil jeg nedenfor vise, hvordan man kan bruge Streaming with DStreams og Streaming with DataFrames (som typisk bruges med Spark Structured Streaming) til at forbruge og behandle data fra Apache Kafka. Jeg vil bruge Scala, Apache Spark 2.3 og Apache Kafka 2.0.
Og for eksemplets skyld vil jeg også køre mine job ved hjælp af Apache Zeppelin-notebooks, der leveres af Qubole. Qubole er en dataplatform, som jeg bruger dagligt. Den administrerer Hadoop- og Spark-klynger, gør det nemt at køre ad hoc Hive- og Presto-forespørgsler og leverer også administrerede Zeppelin-notebooks, som jeg med glæde bruger. Med Qubole behøver jeg ikke at tænke meget over at konfigurere og indstille Spark og Zeppelin, det bliver bare håndteret for mig.
Den faktiske brugssag, jeg har, er meget ligetil:
- En vis form for telemetri skrives til Kafka: små JSON-meddelelser med metadata og vilkårlige nøgle / værdipar
- Jeg ønsker at oprette forbindelse til Kafka, forbruge og deserialisere disse meddelelser
- Derpå anvende transformationer, hvis det er nødvendigt
- Indsamle nogle aggregationer
- Endeligt, Jeg er interesseret i anomalier og generelt dårlige data – da jeg ikke kontrollerer producenten, ønsker jeg at fange ting som NULLs, tomme strenge, måske ukorrekte datoer og andre værdier med specifikke formater osv.
- Jobbet skal køre i et stykke tid og derefter automatisk afsluttes. Typisk kører Spark Streaming-jobs kontinuerligt, men nogle gange kan det være nyttigt at køre det ad hoc til analyse/fejlfinding (eller som et eksempel i mit tilfælde, da det er så nemt at køre et Spark-job i en notesbog).
Streaming med DStreams
I denne tilgang bruger vi DStreams, som simpelthen er en samling RDD’er.
Streaming med DataFrames
Nu kan vi forsøge at kombinere Streaming med DataFrames API for at få det bedste fra begge verdener!
Konklusion
Hvilken tilgang er bedst? Da DStream blot er en samling af RDD’er, bruges den typisk til transformationer og behandling på lavt niveau. Tilføjelse af en DataFrames API oven på dette giver meget kraftfulde abstraktioner som SQL, men kræver en smule mere konfiguration. Og hvis du har en simpel brugssag, er Spark Structured Streaming måske generelt en bedre løsning!