Datenströme vs. DataFrames: Two Flavors of Spark Streaming
Dieser Beitrag ist eine Gastveröffentlichung von Yaroslav Tkachenko, einem Softwarearchitekten bei Activision.
Apache Spark ist eines der beliebtesten und leistungsfähigsten Frameworks für die Verarbeitung großer Datenmengen. Es wurde als Alternative zum MapReduce-Framework von Hadoop für Batch-Workloads entwickelt, aber jetzt unterstützt es auch SQL, maschinelles Lernen und Stream Processing. Heute möchte ich mich auf Spark Streaming konzentrieren und einige Optionen für die Stream-Verarbeitung vorstellen.
Die Stream-Datenverarbeitung wird verwendet, wenn dynamische Daten kontinuierlich generiert werden, und ist häufig in Big-Data-Anwendungsfällen zu finden. In den meisten Fällen werden die Daten nahezu in Echtzeit verarbeitet, ein Datensatz nach dem anderen, und die aus den Daten gewonnenen Erkenntnisse werden auch verwendet, um Warnmeldungen bereitzustellen, Dashboards zu rendern und maschinelle Lernmodelle zu füttern, die schnell auf neue Trends in den Daten reagieren können.
DStreams vs. DataFrames
Spark Streaming wurde mit Spark 0.7.0 eingeführt. Es basiert auf der Idee von diskretisierten Streams oder DStreams. Jeder DStream wird als eine Sequenz von RDDs dargestellt, so dass es einfach zu verwenden ist, wenn Sie von RDD-gestützten Batch-Workloads auf niedriger Ebene kommen. DStreams wurden im Laufe der Zeit stark verbessert, aber es gab immer noch verschiedene Herausforderungen, vor allem weil es sich um eine sehr einfache API handelt.
Als Lösung für diese Herausforderungen wurde Spark Structured Streaming in Spark 2.0 eingeführt (und wurde in 2.2 stabil) als eine Erweiterung, die auf Spark SQL aufbaut. Aus diesem Grund nutzt es die Vorteile von Spark SQL-Code- und Speicheroptimierungen. Structured Streaming bietet auch sehr leistungsfähige Abstraktionen wie Dataset/DataFrame-APIs sowie SQL. Kein direkter Umgang mit RDD mehr!
Sowohl Structured Streaming als auch Streaming mit DStreams verwenden Micro-Batching. Der größte Unterschied besteht in der Latenz und den Garantien für die Nachrichtenübermittlung: Structured Streaming bietet eine exakt einmalige Zustellung mit einer Latenz von 100+ Millisekunden, während der Ansatz von Streaming mit DStreams nur eine mindestens einmalige Zustellung garantiert, aber Latenzen im Millisekundenbereich bieten kann.
Ich persönlich bevorzuge Spark Structured Streaming für einfache Anwendungsfälle, aber Spark Streaming mit DStreams ist aufgrund seiner Flexibilität wirklich gut für kompliziertere Topologien. Deshalb möchte ich im Folgenden zeigen, wie man Streaming mit DStreams und Streaming mit DataFrames (das typischerweise mit Spark Structured Streaming verwendet wird) für den Konsum und die Verarbeitung von Daten aus Apache Kafka verwendet. Ich werde Scala, Apache Spark 2.3 und Apache Kafka 2.0 verwenden.
Auch werde ich, um ein Beispiel zu geben, meine Jobs mit Apache Zeppelin Notebooks ausführen, die von Qubole bereitgestellt werden. Qubole ist eine Datenplattform, die ich täglich verwende. Sie verwaltet Hadoop- und Spark-Cluster, erleichtert die Ausführung von Ad-hoc-Hive- und Presto-Abfragen und bietet außerdem verwaltete Zeppelin-Notebooks, die ich gerne verwende. Mit Qubole muss ich nicht viel über die Konfiguration und Abstimmung von Spark und Zeppelin nachdenken, das wird einfach für mich erledigt.
Der eigentliche Anwendungsfall, den ich habe, ist sehr einfach:
- Eine Art von Telemetrie wird in Kafka geschrieben: Kleine JSON-Nachrichten mit Metadaten und beliebigen Schlüssel/Wert-Paaren
- Ich möchte mich mit Kafka verbinden, diese Nachrichten konsumieren und deserialisieren
- Dann bei Bedarf Transformationen anwenden
- Einige Aggregationen sammeln
- Schließlich, Ich bin an Anomalien und allgemein schlechten Daten interessiert – da ich den Produzenten nicht kontrolliere, möchte ich Dinge wie NULLs, leere Strings, vielleicht falsche Daten und andere Werte mit bestimmten Formaten usw. abfangen.
- Der Auftrag sollte einige Zeit laufen und dann automatisch beendet werden. Normalerweise laufen Spark-Streaming-Jobs kontinuierlich, aber manchmal kann es nützlich sein, sie ad hoc für Analyse/Debugging auszuführen (oder als Beispiel in meinem Fall, da es so einfach ist, einen Spark-Job in einem Notebook auszuführen).
Streaming mit DStreams
Bei diesem Ansatz verwenden wir DStreams, die einfach eine Sammlung von RDDs sind.
Streaming mit DataFrames
Jetzt können wir versuchen, Streaming mit der DataFrames-API zu kombinieren, um das Beste aus beiden Welten zu erhalten!
Abschluss
Welcher Ansatz ist besser? Da DStream nur eine Sammlung von RDDs ist, wird es normalerweise für Low-Level-Transformationen und -Verarbeitung verwendet. Das Hinzufügen einer DataFrames-API bietet sehr leistungsfähige Abstraktionen wie SQL, erfordert aber etwas mehr Konfiguration. Und wenn Sie einen einfachen Anwendungsfall haben, könnte Spark Structured Streaming im Allgemeinen die bessere Lösung sein!