DStreams vs. DataFrames: Two Flavors of Spark Streaming
Tämä postaus on Activisionin ohjelmistoarkkitehti Jaroslav Tkachenkon vierasjulkaisu.
Apache Spark on yksi suosituimmista ja tehokkaimmista suuren mittakaavan tietojenkäsittelykehyksistä. Se luotiin vaihtoehdoksi Hadoopin MapReduce-kehykselle eräajotyömäärille, mutta nyt se tukee myös SQL:ää, koneoppimista ja virtakäsittelyä. Tänään haluan keskittyä Spark Streamingiin ja esitellä muutamia virtauskäsittelyyn käytettävissä olevia vaihtoehtoja.
Stream-tiedonkäsittelyä käytetään silloin, kun dynaamista dataa syntyy jatkuvasti, ja sitä esiintyy usein big data -käyttötilanteissa. Useimmissa tapauksissa dataa käsitellään lähes reaaliajassa, yksi tietue kerrallaan, ja datasta saatuja oivalluksia käytetään myös hälytysten antamiseen, mittaritaulujen renderöintiin ja koneoppimismallien syöttämiseen, jotka voivat reagoida nopeasti datan uusiin trendeihin.
DStreams vs. DataFrames
Spark Streaming tuli alfa-versioksi Sparkin 0.7.0:n myötä. Se perustuu ajatukseen diskretisoiduista virroista eli DStreamsista. Jokainen DStream esitetään RDD:iden sarjana, joten sitä on helppo käyttää, jos tulet matalan tason RDD-pohjaisista erätyömääristä. DStreameihin tehtiin paljon parannuksia tuona aikana, mutta niihin liittyi silti erilaisia haasteita, lähinnä siksi, että kyseessä on hyvin matalan tason API.
Ratkaisuna näihin haasteisiin Spark Structured Streaming otettiin käyttöön Spark 2.0:ssa (ja siitä tuli vakaa 2.2:ssa) laajennuksena, joka on rakennettu Spark SQL:n päälle. Tästä johtuen se hyödyntää Spark SQL:n koodi- ja muistioptimointeja. Structured Streaming tarjoaa myös erittäin tehokkaita abstraktioita, kuten Dataset/DataFrame API:t sekä SQL. Enää ei tarvitse käsitellä RDD:tä suoraan!
Kaikki Structured Streaming ja Streaming with DStreams käyttävät micro-batchingia. Suurin ero on latenssissa ja viestien toimitustakuissa: Structured Streaming tarjoaa täsmälleen yhden kerran toimituksen 100+ millisekunnin latenssilla, kun taas Streaming with DStreams -lähestymistapa takaa vain vähintään yhden kerran toimituksen, mutta voi tarjota millisekunnin latenssit.
Pidän henkilökohtaisesti Spark Structured Streamingista yksinkertaisissa käyttötapauksissa, mutta Spark Streaming with DStreams on todella hyvä monimutkaisempiin topologioihin joustavuutensa vuoksi. Siksi haluan alla näyttää, miten Streaming with DStreamsia ja Streaming with DataFramesia (jota käytetään tyypillisesti Spark Structured Streamingin kanssa) käytetään tietojen kuluttamiseen ja käsittelyyn Apache Kafkasta. Aion käyttää Scalaa, Apache Spark 2.3:aa ja Apache Kafka 2.0:aa.
Sekä esimerkin vuoksi suoritan työni käyttäen Qubolen tarjoamia Apache Zeppelin -muistikirjoja. Qubole on data-alusta, jota käytän päivittäin. Se hallinnoi Hadoop- ja Spark-klustereita, helpottaa ad hoc Hive- ja Presto-kyselyjen suorittamista ja tarjoaa myös hallinnoituja Zeppelin-luetteloita, joita käytän mielelläni. Qubolen avulla minun ei tarvitse juurikaan miettiä Sparkin ja Zeppelinin konfigurointia ja virittämistä, vaan se hoidetaan puolestani.
Varsinainen käyttötapaukseni on hyvin suoraviivainen:
- Jotain telemetriaa kirjoitetaan Kafkaan: Pieniä JSON-viestejä, joissa on metatietoja ja mielivaltaisia avain/arvopareja
- Haluan muodostaa yhteyden Kafkaan, kuluttaa ja deserialisoida nuo viestit
- Sitten soveltaa transformaatioita tarvittaessa
- Kerätä joitain aggregaatioita
- Viimeiseksi, Olen kiinnostunut poikkeavuuksista ja yleisesti huonosta datasta – koska en hallitse tuottajaa, haluan saada kiinni sellaiset asiat kuin NULLit, tyhjät merkkijonot, ehkä virheelliset päivämäärät ja muut arvot tietyissä formaateissa jne.
- Työn pitäisi pyöriä jonkin aikaa ja päättyä sitten automaattisesti. Tyypillisesti Spark Streaming -työt ajetaan jatkuvasti, mutta joskus voi olla hyödyllistä ajaa sitä ad hoc analyysiä/debuggausta varten (tai esimerkkinä minun tapauksessani, koska Spark-työn ajaminen muistikirjassa on niin helppoa).
Streaming with DStreams
Tässä lähestymistavassa käytämme DStreamsia, joka on yksinkertaisesti kokoelma RDD:itä.
Streaming with DataFrames
Nyt voimme kokeilla yhdistää Streamingin ja DataFrames API:n saadaksemme molempien maailmojen parhaan puolen!
Johtopäätökset
Kumpi lähestymistapa on parempi? Koska DStream on vain kokoelma RDD:tä, sitä käytetään tyypillisesti matalan tason muunnoksiin ja käsittelyyn. DataFrames API:n lisääminen sen päälle tarjoaa erittäin tehokkaita abstraktioita kuten SQL, mutta vaatii hieman enemmän konfigurointia. Ja jos sinulla on yksinkertainen käyttötapaus, Spark Structured Streaming saattaa olla yleisesti ottaen parempi ratkaisu!