DStreams vs. DataFrames: Two Flavors of Spark Streaming
Ten post jest publikacją gościnną napisaną przez Yaroslava Tkachenko, Software Architect w Activision.
Apache Spark jest jednym z najpopularniejszych i najpotężniejszych frameworków przetwarzania danych na dużą skalę. Został stworzony jako alternatywa dla Hadoop’s MapReduce framework dla obciążeń wsadowych, ale teraz obsługuje również SQL, uczenie maszynowe i przetwarzanie strumieniowe. Dzisiaj chcę się skupić na Spark Streaming i pokazać kilka opcji dostępnych dla przetwarzania strumieniowego.
Strumieniowe przetwarzanie danych jest używane, gdy dynamiczne dane są generowane w sposób ciągły, i jest często spotykane w przypadkach użycia big data. W większości przypadków dane są przetwarzane w czasie zbliżonym do rzeczywistego, po jednym rekordzie na raz, a spostrzeżenia uzyskane z danych są również wykorzystywane do zapewniania alertów, renderowania pulpitów nawigacyjnych i zasilania modeli uczenia maszynowego, które mogą szybko reagować na nowe trendy w danych.
DStreams vs. DataFrames
Spark Streaming przeszedł w wersji alfa ze Spark 0.7.0. Jest on oparty na idei dyskretnych strumieni lub DStreams. Każdy DStream jest reprezentowany jako sekwencja RDD, więc jest łatwy w użyciu, jeśli pochodzisz z niskopoziomowych obciążeń wsadowych opartych na RDD. DStreams przeszedł wiele ulepszeń w tym okresie czasu, ale nadal istniały różne wyzwania, głównie dlatego, że jest to bardzo niskopoziomowe API.
Jako rozwiązanie tych wyzwań, Spark Structured Streaming został wprowadzony w Spark 2.0 (i stał się stabilny w 2.2) jako rozszerzenie zbudowane na szczycie Spark SQL. Dzięki temu wykorzystuje on optymalizacje kodu i pamięci Spark SQL. Structured Streaming daje również bardzo potężne abstrakcje, takie jak API Dataset/DataFrame, jak również SQL. Nie ma już więcej do czynienia z RDD bezpośrednio!
Oba Structured Streaming i Streaming with DStreams używają mikropatchingu. Największą różnicą jest opóźnienie i gwarancja dostarczenia wiadomości: Structured Streaming oferuje dostawę dokładnie-once z opóźnieniem 100+ milisekund, podczas gdy podejście Streaming with DStreams gwarantuje tylko dostawę at-least-once, ale może zapewnić milisekundowe opóźnienia.
Osobiście wolę Spark Structured Streaming dla prostych przypadków użycia, ale Spark Streaming with DStreams jest naprawdę dobry dla bardziej skomplikowanych topologii ze względu na swoją elastyczność. Dlatego poniżej chcę pokazać jak używać Streaming with DStreams i Streaming with DataFrames (który jest typowo używany ze Spark Structured Streaming) do konsumowania i przetwarzania danych z Apache Kafka. Będę używał Scali, Apache Spark 2.3 i Apache Kafka 2.0.
Ponadto, dla dobra przykładu, będę uruchamiał moje zadania używając notatników Apache Zeppelin dostarczanych przez Qubole. Qubole to platforma danych, z której korzystam na co dzień. Zarządza klastrami Hadoop i Spark, ułatwia wykonywanie zapytań ad hoc Hive i Presto, a także zapewnia zarządzane notebooki Zeppelin, z których chętnie korzystam. Dzięki Qubole nie muszę myśleć o konfigurowaniu i dostrajaniu Sparka i Zeppelina, jest to po prostu obsługiwane za mnie.
Rzeczywisty przypadek użycia, który mam, jest bardzo prosty:
- Jakiś rodzaj telemetrii jest zapisywany do Kafki: małe wiadomości JSON z metadanymi i arbitralnymi parami klucz / wartość
- Chcę połączyć się z Kafką, konsumować i deserializować te wiadomości
- Potem stosować transformacje, jeśli to konieczne
- Zbierać niektóre agregacje
- Wreszcie, Interesują mnie anomalie i ogólnie złe dane – ponieważ nie kontroluję producenta, chcę wyłapać takie rzeczy jak NULL, puste ciągi, być może niepoprawne daty i inne wartości o określonych formatach itp.
- Zadanie powinno działać przez jakiś czas, a następnie automatycznie się zakończyć. Zazwyczaj zadania Spark Streaming działają w sposób ciągły, ale czasami może być użyteczne uruchomienie go ad hoc do analizy/debugowania (lub jako przykład w moim przypadku, ponieważ tak łatwo jest uruchomić zadanie Spark w notatniku).
Streaming z DStreams
W tym podejściu używamy DStreams, który jest po prostu kolekcją RDD.
Streaming z DataFrames
Teraz możemy spróbować połączyć Streaming z DataFrames API, aby uzyskać najlepsze z obu światów!
Wniosek
Które podejście jest lepsze? Ponieważ DStream jest po prostu kolekcją RDD, jest zwykle używany do niskopoziomowych transformacji i przetwarzania. Dodanie API DataFrames na wierzchu zapewnia bardzo potężne abstrakcje, takie jak SQL, ale wymaga nieco więcej konfiguracji. A jeśli masz prosty przypadek użycia, Spark Structured Streaming może być lepszym rozwiązaniem w ogóle!