Structured Streaming ist die Schnittstelle (API) der Datenverarbeitungs-Plattform Apache Spark für kontinuierlich eintreffende Daten. Der Trick: Ein laufender Datenstrom (z. B. Klick-Ereignisse aus einer Web-App) wird behandelt wie eine Tabelle, die ständig um neue Zeilen wächst. Auswertungen darauf werden mit denselben SQL-Abfragen geschrieben wie auf einer gewöhnlichen, abgeschlossenen Tabelle. Die Engine übernimmt im Hintergrund die schwierigen Teile: Ausfallsicherheit, garantiert einmalige Verarbeitung jedes Ereignisses und den Umgang mit verspätet eintreffenden Daten.
Was ist Structured Streaming?
Structured Streaming ist die Streaming-Schicht von Apache Spark, eingeführt in Spark 2.0 (2016) und seit Spark 2.2 (2017) als produktionsreife API markiert. Die Idee dahinter ist einfach: Ein Datenstrom wird als Tabelle betrachtet, an die pausenlos neue Zeilen angehängt werden. Eine Auswertung wie „zähle die Klicks pro Seite in der letzten Minute" wird als normale SQL-Abfrage formuliert, und die Engine wendet sie automatisch immer wieder auf die neu hinzugekommenen Zeilen an. Derselbe Programmcode funktioniert damit sowohl auf einer statischen Datei als auch auf einem laufenden Stream. Der einzige Unterschied liegt darin, wie die Daten eingelesen und geschrieben werden (readStream statt read, writeStream statt write).
Standard-Ausführungsmodell ist der Micro-Batch-Trigger: die Engine gruppiert eintreffende Ereignisse in kleine Batches (typisch Sekunden bis Minuten) und plant für jeden Batch einen kompletten Spark-Job über den Catalyst-Optimizer und die Tungsten-Execution. Alternativ steht der Continuous-Trigger zur Verfügung, der einzelne Operatoren im Event-für-Event-Modus mit Millisekunden-Latenz ausführt; er ist experimentell und unterstützt nur einen eingeschränkten Operator-Satz.
Die Engine liefert End-to-End Exactly-Once-Semantik, wenn Quelle und Senke die Voraussetzungen erfüllen. Der Streaming-Fortschritt wird pro Micro-Batch in Checkpoints und einem Write-Ahead-Log persistiert; nach einem Ausfall setzt der Job an genau der letzten committeten Position wieder auf. Für nicht-transaktionale Senken (etwa REST-Endpunkte) übernimmt der Anwendungscode die Idempotenz.
Für zeitbasierte Auswertungen unterstützt Structured Streaming Event-Time-Windowing mit tumbling, sliding und session-basierten Fenstern. Watermarks steuern, wie lange die Engine auf verspätete Events wartet, bevor ein Fenster geschlossen und der zugehörige State verworfen wird. Zustandsbehaftete Operatoren wie Aggregationen, Stream-Stream-Joins, Deduplizierung und flatMapGroupsWithState halten Zwischenzustände in einem [State-Store](https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html); Standard ist ein HDFS-Backed State-Store, für hohe Zustandsvolumina steht ein [RocksDB-Backend](https://docs.databricks.com/aws/en/structured-streaming/rocksdb-state-store) zur Verfügung.
Als Quellen kommen Kafka, Kinesis, Pub/Sub, Delta-Tabellen im Streaming-Modus und Auto Loader auf Cloud Storage in Frage; als Senken Delta Lake, Kafka, Files, JDBC oder eine foreach-Sink für beliebige Ziele. Structured Streaming ist die Ausführungsschicht, auf der Databricks-Streaming-Jobs, [Lakeflow Declarative Pipelines](https://docs.databricks.com/aws/en/dlt/) (früher Delta Live Tables) und Spark Declarative Pipelines aufsetzen: die deklarativen Frameworks exponieren die Streaming-Mechanik als Tabellen-Definitionen und übernehmen Checkpoints, Watermarks und Wiederanlauf automatisch.
Abgrenzung zu DStream, Flink, Kafka Streams und Data Streaming
Structured Streaming wird häufig mit anderen Streaming-Engines und mit dem Oberbegriff Data Streaming vermengt. Die Trennlinien laufen entlang API-Generation, Verarbeitungsmodell und der Frage, ob es sich um eine Engine oder ein Konzept handelt.
| Begriff | Verhältnis zu Structured Streaming |
|---|---|
| DStream (Spark Streaming) | Vorgänger-API auf RDD-Basis mit „discretized streams". Fehlt Catalyst-Optimizer, Event-Time-Semantik und End-to-End Exactly-Once. Seit Spark 3.4 deprecated. |
| Apache Flink | Native True-Streaming-Engine mit Event-für-Event-Verarbeitung und eigenem State-Backend. Structured Streaming arbeitet standardmäßig in Micro-Batches; Latenz-Trade-off zugunsten des gemeinsamen Programmiermodells mit Batch. |
| Kafka Streams | JVM-Bibliothek, die Streaming-Logik direkt in einer Anwendung neben einem Kafka-Cluster ausführt. Läuft ohne Spark-Cluster, ohne DataFrame-API und ohne direkten Lakehouse-Zugriff. |
| Data Streaming | Verarbeitungsmodell (kontinuierliche Ereignisverarbeitung); Structured Streaming ist eine konkrete Engine-Umsetzung dieses Modells. |
| Streaming Analytics | Analytischer Einsatzzweck (Kennzahlen, Muster, Alerts); Structured Streaming ist eine mögliche Ausführungsschicht darunter. |
Der wichtigste API-interne Unterschied liegt zwischen DStream und Structured Streaming: der Wechsel von RDD zu DataFrame ist die Voraussetzung für Catalyst-Optimierung, deklarative Event-Time-Semantik und Exactly-Once. Neue Streaming-Anwendungen in Spark werden ausschließlich mit Structured Streaming geschrieben.
Gegenüber Flink liegt der zentrale Unterschied im Ausführungsmodell. Flink verarbeitet jedes Event einzeln und erreicht damit Latenzen im niedrigen Millisekundenbereich, verlangt aber ein eigenes State- und Deployment-Modell. Structured Streaming liefert Micro-Batch-Latenzen im Sekundenbereich (Continuous Processing niedriger, dafür mit Operator-Einschränkungen), bindet dafür Batch und Stream in derselben DataFrame-API und läuft auf jedem Spark-Cluster ohne zusätzliche Infrastruktur.
Beispiel: Kafka-Stream in eine Delta-Tabelle
Ein typischer Structured-Streaming-Job liest Klick-Ereignisse aus einem Kafka-Topic, aggregiert sie in 1-Minuten-Sliding-Windows und schreibt die Aggregate als Delta-Tabelle für ein Near-Real-Time-Dashboard.
from pyspark.sql.functions import window, col, from_json
from pyspark.sql.types import StructType, StringType, TimestampType
schema = (StructType()
.add("user_id", StringType())
.add("event_time", TimestampType())
.add("page", StringType()))
events = (spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "kafka:9092")
.option("subscribe", "clicks")
.load()
.select(from_json(col("value").cast("string"), schema).alias("e"))
.select("e.*"))
agg = (events
.withWatermark("event_time", "2 minutes")
.groupBy(window("event_time", "1 minute", "30 seconds"), "page")
.count())
query = (agg.writeStream
.format("delta")
.outputMode("append")
.option("checkpointLocation", "s3://prod/checkpoints/clicks_1m/")
.trigger(processingTime="30 seconds")
.toTable("analytics.clicks_1m"))Der Job pollt alle 30 Sekunden neue Events aus Kafka, fenstert sie über die Event-Zeit in überlappenden Ein-Minuten-Fenstern, verwirft Events mit mehr als zwei Minuten Verspätung und hängt die Aggregate an die Delta-Tabelle analytics.clicks_1m an. Der checkpointLocation sichert den Kafka-Offset-Stand und den Fenster-State ab; nach einem Neustart konsumiert der Job genau ab dem letzten committeten Offset weiter, und die Delta-Senke garantiert Exactly-Once auf Tabellen-Ebene.
Weitere klassische Einsatzfelder sind die CDC-Ingestion aus Debezium-Kafka-Streams mit MERGE INTO in eine Silver-Delta-Tabelle, die Verarbeitung von IoT-Telemetrie mit stateful-Deduplizierung sowie die kontinuierliche Feature-Berechnung für Online-Model-Serving.
Structured Streaming im eigenen Unternehmen umsetzen?
Wir zeigen, wie sich das in deiner Systemlandschaft konkret abbilden lässt.
Entscheidungskontext für kontinuierliche Verarbeitung und Positionierung gegen inkrementellen Batch
Data Engineering auf DatabricksEinordnung in Ingest- und Verarbeitungsbausteine
Spark Declarative Pipelinesdeklarative Ebene, die Structured Streaming als Ausführungsschicht nutzt
Apache Sparkverteilte Engine, in die Structured Streaming als API eingebettet ist
DatenstreamingVerarbeitungsmodell als Oberbegriff
Streaming Analyticsanalytische Nutzungsklasse, für die Structured Streaming eine Ausführungsschicht liefert
Spark Declarative Pipelines (Glossar)deklaratives Pipeline-Framework, das auf Structured Streaming aufsetzt
Delta Laketransaktionale Senke, die Exactly-Once auf Tabellen-Ebene garantiert