Google PDE: Stream-Verarbeitung mit Dataflow und Apache Beam — Lernleitfaden
Teil des Google Professional Data Engineer — Lernleitfaden. Üben Sie mit verifizierten Antworten im Google-Prüfungscenter, oder absolvieren Sie zeitlich begrenzte Übungstests auf ExamRoll.io.
Überblick
Die Stream-Verarbeitung in der Google Cloud basiert auf dem einheitlichen Programmiermodell von Apache Beam, das vom Dataflow-Runner ausgeführt wird. Beam bietet eine logische Abstraktion – Pipelines von Transformationen über PCollections –, die Ihren Code von Ausführungsdetails wie Parallelität, Autoskalierung und Fehlertoleranz entkoppelt. Beim Streaming hängt die Korrektheit von der Zeitsemantik (Ereigniszeit vs. Verarbeitungszeit), dem Windowing (feste, gleitende, Sitzungs-, globale Fenster), Watermarks, Triggern und der Behandlung verspäteter Daten ab. Ein exzellenter Betrieb auf Dataflow erfordert die richtige Worker-Größe, eine passende Autoskalierungsrichtlinie, die Wahl der Streaming-Engine und der Shuffle-Optionen, ein idempotentes Senken-Design, die Handhabung von Dead-Letter-Nachrichten und eine robuste Observability.
Apache-Beam-Modell und Zeitsemantik
Pipelines, Transformationen, PCollections, Runner:
- Eine Beam-Pipeline wendet einen gerichteten azyklischen Graphen von PTransforms auf PCollections (begrenzt oder unbegrenzt) an.
- Runner (Dataflow, Spark, Flink, Direct) führen die Pipeline aus; Dataflow bietet verwaltete Autoskalierung, Checkpointing und operative Einblicke.
- Transformationen umfassen elementweise (ParDo), Gruppierung und Kombination (GroupByKey, Combine), Joins (CoGroupByKey) und IOs (PubSubIO, BigQueryIO, FileIO).
Fenster (Windows):
- Feste Fenster (Fixed Windows): sich nicht überlappende Zeitabschnitte (z. B. 1-minütige Tumbling Windows) für periodische Aggregate.
- Gleitende Fenster (Sliding Windows): überlappende Fenster für gleitende Metriken (z. B. 5-Minuten-Fenster, die sich jede Minute verschieben).
- Sitzungsfenster (Session Windows): dynamische Fenster, die sich nach einer Inaktivitätspause schließen, ideal für Benutzersitzungen oder Geräte-Bursts.
- Globales Fenster (Global Window): die standardmäßige, nicht gefensterte Ansicht des gesamten unbegrenzten Streams; oft mit Triggern für die periodische Materialisierung kombiniert.
Ereigniszeit vs. Verarbeitungszeit:
- Ereigniszeit (Event Time): der Zeitpunkt, zu dem das Ereignis an der Quelle aufgetreten ist; ermöglicht logisch konsistente Aggregationen trotz variabler Transportlatenzen.
- Verarbeitungszeit (Processing Time): der Zeitpunkt, zu dem das Ereignis von der Pipeline beobachtet wird; nützlich für operative Trigger, aber nicht für die semantische Korrektheit.
Watermarks:
- Ein Watermark schätzt die Vollständigkeit der Ereigniszeit (die Annahme des Runners, dass er alle Ereignisse bis zum Zeitpunkt T gesehen hat).
- Watermarks können sich unregelmäßig vorwärtsbewegen oder bei Gegendruck (Backpressure) oder Quellenverzögerungen stagnieren; verspätete Daten (Late Data) sind alle Daten, die mit einem Zeitstempel < Watermark eintreffen.
Trigger und Verspätung (Lateness):
- Standard: AfterWatermark-Trigger, der auslöst, wenn der Watermark das Fensterende passiert; bei
allowed lateness = 0werden verspätete Daten verworfen. - Frühe Auslösungen (Early Firings) (verarbeitungszeit- oder anzahlbasiert) liefern vorläufige Ergebnisse mit geringer Latenz.
- Späte Auslösungen (Late Firings) ermöglichen Korrekturen, wenn verspätete Daten eintreffen; der Akkumulationsmodus (Accumulation Mode) steuert, ob Panes Ergebnisse ansammeln oder frühere Ausgaben verwerfen.
- Wählen Sie die zulässige Verspätung (Allowed Lateness) basierend auf der Geschäftstoleranz und den Kompromissen zwischen Speicher und Rechenleistung; eine größere Verspätung erhöht die Vorhaltezeit des Zustands (State) und die Kosten.
- Standard: AfterWatermark-Trigger, der auslöst, wenn der Watermark das Fensterende passiert; bei
Zustandsbehaftete Verarbeitung, Timer, Sessionization, Deduplizierung:
- Zustandsbehaftete DoFns (Stateful DoFns) halten einen Zustand pro Schlüssel (z. B. zuletzt gesehenes Ereignis, laufende Aggregate) und setzen Timer, um den Zustand auszugeben oder zu löschen.
- Sessionization wird natürlich über SessionWindows ausgedrückt; für benutzerdefinierte Logik verwenden Sie zustandsbehaftete Schlüssel (Keyed State) und Verarbeitungs-/Ereigniszeit-Timer.
- Deduplizierung: Verwenden Sie eine stabile ID pro Ereignis und entweder Distinct/Combine pro Fenster oder einen Zustand pro Schlüssel (z. B. Bloom-Filter oder ein Set mit TTL). Wägen Sie zwischen Speicherverbrauch und Falsch-Positiven (False Positives) gegenüber strikter Genauigkeit ab.
Fehlermodi und Kompromisse:
- Die Verwendung von Verarbeitungszeit-Fenstern für Geschäftsmetriken führt bei Lastspitzen oder Wiederholungsversuchen zu Abweichungen (Drift); bevorzugen Sie Ereigniszeit-Fenster.
- Zu kleine Fenster mit häufigen frühen Triggern verursachen eine übermäßige Ausgabe von Panes und eine Schreibverstärkung in der Senke (Sink Write Amplification).
- Eine unbegrenzte zulässige Verspätung (Allowed Lateness) kann den Zustand (State) aufblähen; begrenzen Sie immer die TTL des Zustands und setzen Sie Timer, um ruhende Schlüssel zu löschen.
Betrieb von Dataflow für Streaming-Workloads
Worker-Größenanpassung und Autoscaling:
- Horizontales Autoscaling fügt Worker basierend auf Backlog, Watermark-Verzögerung, CPU und Durchsatz hinzu oder entfernt sie; legen Sie einen sinnvollen
maxWorkers-Wert fest, um Lastspitzen abzufangen. - Wählen Sie Maschinentypen entsprechend den Engpässen: CPU-gebunden (mehr vCPUs), speichergebunden (High-Memory-Typen), netzwerkgebunden (größere VMs reduzieren den Shuffle-Overhead).
- Erhöhen Sie die Boot-Disk bei intensiven Shuffles oder dateibasierten Sinks. Überwachen Sie System-Lag und Backlog in Sekunden.
- Horizontales Autoscaling fügt Worker basierend auf Backlog, Watermark-Verzögerung, CPU und Durchsatz hinzu oder entfernt sie; legen Sie einen sinnvollen
Streaming Engine und Shuffle:
- Die Streaming Engine lagert den Zustand (State) und den Shuffle in das Service-Backend aus, was die Elastizität verbessert, den Speicherdruck auf die Worker reduziert und schnellere Updates ermöglicht.
- Für Batch-lastige Stufen oder massives Gruppieren von Schlüsseln (Key-Grouping) verwenden Sie Dataflow Shuffle, um den Shuffle-I/O von den Workern auszulagern. Beides reduziert Ausfälle durch Hot-Worker und Disk-Thrashing.
Backpressure, Hot Keys und Skew:
- Dataflow steuert Backpressure durch dynamische Neuverteilung der Arbeit (Work Rebalancing); passen Sie dennoch, falls zutreffend, die Flusskontrolle der Quelle an (z. B. ausstehende Nachrichten/Bytes bei Pub/Sub).
- Hot Keys (z. B. populäre IDs) erzeugen Nachzügler (Stragglers). Mildern Sie dies durch Key-Sharding (key#N), partielle Vorab-Aggregation mit anschließendem Re-Keying oder skizzenbasierte Annäherungen.
- Skew durch Ausreißer-Datensätze (riesige Payloads) oder stoßweise sendende Publisher kann Partitionen pro Publisher, Batching oder Komprimierung erfordern.
Pub/Sub-Integration:
- Verwenden Sie Pub/Sub-Topics für die Ingestion; aktivieren Sie Nachrichtenattribute für Metadaten (z. B. deviceId, Event-Zeitstempel).
- Nehmen Sie Daten mit PubSubIO auf; extrahieren Sie Event-Zeitstempel aus Attributen oder dem Payload, andernfalls greifen Sie auf die Veröffentlichungszeit (Publish Time) zurück.
- Ordnungsschlüssel (Ordering Keys) gewährleisten eine Reihenfolge pro Schlüssel; Dataflow benötigt aufgrund der „at-least-once“-Zustellung dennoch idempotentes Verhalten in nachgelagerten Systemen.
Muster für das Streaming nach BigQuery:
- Bevorzugen Sie BigQueryIO mit der Storage Write API für hohen Durchsatz und „exactly-once“-Semantik mit niedriger Latenz innerhalb eines Streams durch Stream-Offsets und automatische Wiederholungsversuche.
- Für einfache Pipelines mit geringer Rate sind Streaming-Inserts akzeptabel; setzen Sie die
insertId, um clientseitige Wiederholungsversuche zu deduplizieren. - Abfragen über Streaming-Puffer sind „eventually consistent“; für zeitkritische Analysen fragen Sie nach einer Pufferverzögerung ab (z. B. ~2x der beobachteten Verfügbarkeitslatenz warten) oder materialisieren Sie die Daten über Micro-Batch-Fenster und den Committed-Modus der Storage Write API.
Exactly-once-Effekte, Idempotenz, Replay und Sinks:
- Beam garantiert eine „at-least-once“-Verarbeitung; „exactly-once“ muss am Sink durch idempotente Schreibvorgänge, Transaktionen oder Deduplizierungsschlüssel erreicht werden.
- BigQuery: Verwenden Sie Default-Streams oder Committed-Streams der Storage Write API für „exactly-once“ innerhalb eines Streams; bei Streaming-Inserts setzen Sie eine stabile
insertId. - Dateien: Schreiben Sie temporäre Dateien mit eindeutigen Namen, finalisieren Sie diese bei Abschluss des Fensters und stellen Sie atomare Umbenennungen sicher; vermeiden Sie Überschreiben, um partielle Duplikate zu verhindern.
- Externe Datenbanken: Verwenden Sie Upserts mit einer stabilen ID als Schlüssel oder implementieren Sie Deduplizierungsfenster.
- Für Replay auslegen: Behalten Sie deterministische Transformationen bei; stellen Sie sicher, dass Sinks bei Wiederholungsversuchen deduplizieren.
Dead-Letter-Handling, Fehler-Routing und Observability:
- Kapseln Sie riskantes Parsen/Anreichern in
try/catch-Blöcke innerhalb von ParDo und leiten Sie Fehler über einen TupleTag an eine Dead-Letter-PCollection weiter; fügen Sie Payload, Fehlercode und Kontext hinzu. - Leiten Sie DLQs (Dead-Letter-Queues) zur Analyse an BigQuery oder Cloud Storage weiter; ziehen Sie ein separates Pub/Sub-Topic für die Wiederverarbeitung in Betracht.
- Observability: Nutzen Sie Dataflow-Job-Metriken (Watermark-Verzögerung, System-Lag, Durchsatz), benutzerdefinierte Zähler (Custom Counters), Verteilungsmetriken und Logs pro Schritt in Cloud Logging. Erstellen Sie Alerting für Verzögerungen und Fehlerraten in Cloud Monitoring. Verwenden Sie Error Reporting, um Ausnahmen zu aggregieren.
- Kapseln Sie riskantes Parsen/Anreichern in
Muster zur Leistungsoptimierung:
- Effizient lesen: Bevorzugen Sie für BigQuery-Quellen die Storage Read API oder abfragebasierte Lesevorgänge, die nur die benötigten Felder und Filter auswählen.
- Combine-Lifting: Verwenden Sie Combiner, um das Shuffle-Volumen vor einem GroupByKey zu reduzieren.
- Side-Inputs: Cachen Sie kleine Referenzdaten im Speicher; achten Sie auf den Fan-Out und die Aktualisierungsfrequenz.
- Serialisierung: Verwenden Sie kompakte Schemata (Avro/Proto) und vermeiden Sie übermäßiges JSON-Parsing auf Hot Paths (kritischen Pfaden).
Bereitstellung, Vorlagen und Upgrade-Strategien
Flex Templates:
- Bündeln Sie Pipelines in containerisierten, parametrisierten Vorlagen für reproduzierbare Bereitstellungen. Flex Templates unterstützen benutzerdefinierte Abhängigkeiten, GPU-Images und eine isolierte Umgebung.
- Externalisieren Sie Laufzeitparameter (z. B. Input-Subscription, Output-Tabelle, Dead-Letter-Sink, maxWorkers), um umgebungsspezifische Bereitstellungen zu ermöglichen.
Pipeline-Updates und Kompatibilität:
- Dataflow unterstützt In-Place-Updates für viele Streaming-Pipelines, wenn die Namen der Transformationen, die Zustandsspezifikationen (State Specs) und die Ausgabetypen kompatibel bleiben. Verwenden Sie stabile PTransform-Namen.
- Bei inkompatiblen Änderungen am Graphen oder Zustand führen Sie einen kontrollierten Cutover durch: Starten Sie den neuen Job und leeren (drain) Sie dann den alten Job, um die laufende Verarbeitung abzuschließen und das Lesen neuer Elemente zu beenden.
Draining und Snapshots:
- Das Leeren (Drain) schließt die Verarbeitung ordnungsgemäß ab, schreibt die verbleibende Ausgabe und beendet den Job; koordinieren Sie dies mit der Pub/Sub-Aufbewahrungsfrist (Retention) oder Snapshots, um Lücken zu vermeiden.
- Um die Kontinuität zu gewährleisten, können Sie einen Pub/Sub-Snapshot erstellen, die neue Pipeline starten, die auf den Snapshot oder einen geeigneten Zeitstempel zugreift (seek), die Ausgabe überprüfen und dann den alten Job leeren (drain).
Konfigurationsbeispiele:
- Beispiel für Windowing mit Early/Late Triggers und Akkumulation:
undefined
- Beispiel für BigQueryIO mit der Storage Write API:
undefined
- Häufige Fallstricke:
- Das Schreiben in dateibasierte Sinks im Streaming-Modus ohne fensterbasiertes Schreiben (Windowed Writes) kann die Finalisierung blockieren; aktivieren Sie fensterbasiertes Schreiben und Trigger.
- Unbegrenztes Wachstum (Unbounded Growth): Wenn der Zustand (State) oder die zulässige Verspätung (Allowed Lateness) nicht begrenzt werden, kann dies zu Speicherlecks und Skalierungsfehlern führen.
- Fehlende Zeitstempel: Wenn keine Ereigniszeitstempel zugewiesen werden, verwendet die Pipeline standardmäßig die Verarbeitungszeit (Processing Time), was bei variablen Verzögerungen zu fehlerhaften Ergebnissen führt.
Praktisches Problemszenario
NovaTrack Inc. erfasst globale IoT-Telemetriedaten von 50.000 Temperatursensoren und muss minutengenaue Aggregate liefern, Rohdaten persistieren und ein Echtzeit-Dashboard bereitstellen. Gelegentlich fehlerhafte Nachrichten und eine außerplanmäßige Zustellung (out-of-order) sind zu erwarten. Die Lösung muss automatisch skalieren, fehlerhafte Datensätze zur Überprüfung bereitstellen und Upgrades ohne Ausfallzeiten unterstützen.
Ansatz:
Ingestion und Zeitsemantik
- Erstellen Sie ein regionales Pub/Sub-Thema und pro Region Publisher mit den Attributen deviceId und eventTs (RFC3339). Aktivieren Sie, wenn möglich, Ordering Keys nach deviceId.
- Begründung: Pub/Sub bietet einen langlebigen, elastischen Ingress mit At-least-once-Zustellung. Das Anhängen von Ereigniszeitstempeln am Edge bewahrt die wahre Ereigniszeit; die Sortierung pro Gerät reduziert die Neuordnung innerhalb eines Geräts ohne zentrale Engpässe.
Dataflow-Streaming-Pipeline mit Ereigniszeit-Fenstern (Event-Time Windows)
- Lesen Sie aus einer dedizierten Subscription über PubSubIO, extrahieren Sie eventTs als Beam-Zeitstempel und verwenden Sie publishTime als Fallback, falls dieser fehlt.
- Wenden Sie FixedWindows von 1 Minute mit einem Early Trigger nach 30 Sekunden und Late Firings für jedes verspätete Element an; setzen Sie die zulässige Verspätung (Allowed Lateness) auf 10 Minuten und akkumulieren Sie die Panes.
- Begründung: Ereigniszeit-Fenster gewährleisten genaue Minutenaggregate; Early Firings versorgen das Dashboard mit unterminütiger Aktualität; Late Firings korrigieren Aggregate, wenn verspätete Daten eintreffen. Die Begrenzung der Verspätung deckelt die Zustandsgröße (State Size) und die Kosten.
Validierung, Anreicherung und Dead-Letter-Routing
- Implementieren Sie eine ParDo-Transformation, die JSON parst, Schema und Wertebereiche validiert und mit kleinen statischen Referenzdaten über einen Side-Input anreichert, der beim Job-Start aus BigQuery geladen wird.
- Verwenden Sie TupleTags, um gültige Datensätze an den Haupt-Output und fehlerhafte an eine Dead-Letter-PCollection auszugeben, die Payload, Fehler, deviceId und Parse-Zeitstempel enthält; schreiben Sie die DLQ in eine partitionierte BigQuery-Tabelle.
- Begründung: Side-Inputs halten Referenzdaten für geringe Latenz im Speicher. Die Erfassung in einer Dead-Letter-Queue ermöglicht die Überprüfung und gezielte Neuverarbeitung fehlerhafter Zeilen, ohne den Hauptfluss zu blockieren.
Aggregation und Hot-Key-Mitigation
- Gruppieren Sie nach deviceId und berechnen Sie pro Minute avg/min/max mit CombineFns. Für Top-N-Regionalmetriken sharden Sie nach region#N, um Hot Keys zu vermeiden, und aggregieren Sie dann erneut.
- Begründung: Combiner minimieren das Shuffle-Volumen und die Kosten; Key-Sharding verhindert Engpässe durch einzelne Schlüssel während des regionalen Fan-Ins.
Sinks und Exactly-Once-Effekte
- Schreiben Sie validierte Rohdatenereignisse und Minutenaggregate mit BigQueryIO und der Storage Write API nach BigQuery. Setzen Sie eine stabile Insert-ID basierend auf deviceId + eventTs für Idempotenz bei benutzerdefinierten Wiederholungsversuchen (Retries).
- Begründung: Die Storage Write API bietet eine Ingestion mit hohem Durchsatz und geringer Latenz mit Exactly-Once-Semantik innerhalb eines Streams. Stabile IDs gewährleisten die nachgelagerte Deduplizierung, falls Wiederholungen (Replays) auftreten.
Strategie für die Dashboard-Konsistenz
- Das Dashboard fragt partitionierte Aggregat-Tabellen mit einem Rückblick (Lookback) von 2 Minuten relativ zum Watermark oder einer festen Verzögerung von 2x der beobachteten Verfügbarkeitslatenz für Streaming-Daten ab.
- Begründung: Die Sichtbarkeit von BigQuery-Streaming ist Eventually Consistent; eine leichte Verzögerung der Lesezugriffe verhindert fehlende, sich in Verarbeitung befindliche Zeilen (in-flight) und bewahrt gleichzeitig ein Nahezu-Echtzeit-Verhalten.
Betrieb: Autoscaling und Streaming Engine
- Aktivieren Sie die Streaming Engine; setzen Sie maxWorkers basierend auf der erwarteten Spitzenlast (z. B. 3x Durchschnitt), wählen Sie einen Maschinentyp, der für CPU-gebundenes Parsen und Verschlüsselung ausgelegt ist, und vergrößern Sie die Boot-Disk, um transientes Shuffle zu bewältigen.
- Überwachen Sie Watermark-Lag, Backlog in Sekunden, CPU und den Durchsatz pro Schritt; richten Sie Alarme für anhaltenden Lag und Spitzen in der DLQ-Rate ein.
- Begründung: Die Streaming Engine externalisiert Zustand (State) und Shuffle für mehr Elastizität und einfachere Upgrades; die richtige Dimensionierung (Right-Sizing) und Überwachung verhindern stille SLO-Verletzungen.
Bereitstellung und Upgrades mit Flex Templates
- Bündeln Sie die Pipeline als Flex Template mit Parametern: Input-Subscription, Output-Tabellen, DLQ-Tabelle, maxWorkers und Region. Bei einer inkompatiblen Änderung starten Sie die neue Pipeline, die auf dasselbe Topic mit einer neuen Subscription zielt, überprüfen Sie die Ausgaben und leeren (drain) Sie dann den alten Job. Erstellen Sie optional einen Pub/Sub-Snapshot und lassen Sie die neue Subscription auf den Snapshot zugreifen (seek), um Lücken zu garantieren.
- Begründung: Flex Templates ermöglichen wiederholbare, parametrisierte Bereitstellungen. Ein verifizierter Blue/Green-Cutover mit Drain erreicht null Datenverlust und minimale Ausfallzeiten.
Neuverarbeitung und Batch-Backfills
- Speichern Sie komprimierte Avro-Dateien der Rohdatenereignisse über einen Side-Output in Cloud Storage; führen Sie eine Batch-Dataflow-Pipeline aus, um Daten nachzufüllen (Backfill) oder neu zu verarbeiten, wenn sich Modelle oder Schemata ändern.
- Begründung: Dauerhafte Rohdatenarchive unterstützen die Reproduzierbarkeit und Schema-Evolution, ohne den Hot Path zu beeinträchtigen.
Dieses Design liefert korrekte Aggregate mit geringer Latenz bei begrenzten Kosten, klarer Fehlerisolierung, starker Observability und sicheren Upgrade-Pfaden, während es gleichzeitig außerplanmäßige und verspätete Daten im globalen Maßstab verarbeitet.
← BigQuery Analytics und Warehouse-Engineering · Alle Domänen · Messaging →
Diese Fragen üben → · Zeitlich begrenzte Übung auf ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Bestehe deine Prüfung →