Direkt zum Hauptinhalt
Produkt

AUTO CDC auf das nächste Level bringen: Die schwierigsten realen Anwendungsfälle lösen

Von bitemporaler Compliance bis hin zu partiellen Datensatz-Updates: Bereitstellung von robustem, revisionssicherem Change Data Capture ohne benutzerdefinierten Code

von Josh Seidel, Shanelle Roman und Sudhanva Huruli

  • AUTO CDC ersetzt handgeschriebene MERGE-Logik für Change Data Capture durch eine deklarative Pipeline
  • Spark Declarative Pipelines unterstützt jetzt bitemporales AUTO CDC, um Geschäfts- und Systemzeit unabhängig voneinander zu erfassen, sowie Partial Updates zur sicheren Handhabung fehlender Felder
  • Die Funktionen von AUTO CDC werden auf das Open-Source-Projekt Apache Spark 4.2 ausgeweitet, um dem breiteren Ökosystem ein standardisiertes Out-of-Order-Change-Data-Capture bereitzustellen

Die Erfassung von Datenänderungen (Change Data Capture, CDC) gehört zu den häufigsten Aufgaben, die Data Engineers auf Spark aufbauen, und ist manuell besonders mühsam fehlerfrei umzusetzen. In unserem vorherigen Beitrag Schluss mit dem manuellen Schreiben von Change-Data-Capture-Pipelines haben wir gezeigt, wie AUTO CDC in Apache™ Spark Declarative Pipelines (SDP) SCD Typ 1, SCD Typ 2 und Snapshot-CDC automatisiert, indem Hunderte von Zeilen fehleranfälliger MERGE-Logik durch wenige einfache Deklarationen ersetzt werden.

Da sich die Anforderungen an Pipelines ständig weiterentwickeln, stoßen Engineers auf Situationen, die mit diesen Standard-CDC-Mustern nur schwer zu lösen sind:

  • Umgang mit ungeordneten bitemporalen Zeitachsen
  • Verarbeitung von partiellen Datensatz-Aktualisierungen, ohne bestehende Daten zu beschädigen
  • Aufrechterhaltung der Revisionssicherheit über die Aufbewahrungsfristen des Speichers hinaus

Heute heben wir AUTO CDC auf die nächste Stufe, um genau diese praktischen Herausforderungen zu lösen, und erweitern diese Funktionen im Open-Source-Projekt Apache Spark 4.2.

Zweiachsige Verlaufserfassung mit bitemporalem AUTO CDC

Standard-SCD-Typ-2-Tabellen können Ihnen zwar sagen, wann sich ein Fakt in der realen Welt geändert hat, aber nicht, welchen Zustand Ihr System zu einem bestimmten Zeitpunkt angenommen hat.

Gemäß der SEC-Regel 17a-4 und den FINRA-Aufbewahrungsvorschriften müssen Unternehmen in der Lage sein, Datensätze so zu rekonstruieren, wie sie zu einem bestimmten Zeitpunkt existierten. Allein die SEC-Untersuchungen zur Einhaltung der Aufbewahrungspflichten haben seit 2021 zu Bußgeldern von über 2 Milliarden US-Dollar bei mehr als 100 Unternehmen geführt. Die Schwierigkeit liegt selten darin, den heutigen Wert zu speichern. Die Herausforderung besteht darin, Monate später zu beantworten, was die Referenzdaten am Berichtstag besagten und welchen Zustand unsere Systeme zu diesem Zeitpunkt angenommen hatten.

Standard-SCD-Typ-2 erfasst eine Zeitachse: wann sich ein Fakt geändert hat. Bitemporales AUTO CDC erfasst zwei Zeitachsen unabhängig voneinander:

  • Gültigkeitszeit (Business Time) (auch bekannt als Ereignis- oder Validierungszeit): wann der Fakt in der realen Welt tatsächlich zutraf. Ein Börsenkürzel wurde am Montag meldepflichtig; ein Ländercode wurde am Ende des Quartals deaktiviert.
  • Systemzeit (System Time) (auch bekannt als Transaktions- oder Verarbeitungszeit): wann das führende System von den Daten erfahren hat. Die Änderung vom Montag geht möglicherweise erst am Mittwoch in der Pipeline ein.

Jede Zieltabelle erhält vier systemseitig verwaltete Spalten: __START_AT und __END_AT für die Gültigkeitszeit (Business Time) sowie __SYSTEM_START_AT und __SYSTEM_END_AT für die Systemzeit. Ein einzelner logischer Fakt kann mehrere physische Zeilen haben – eine pro Kombination aus Business-Version und System-Version. Dies ermöglicht die historische Rekonstruktion entlang beider Achsen. Die wichtigste Verhaltensgarantie dabei: Ereignisse können in beliebiger Reihenfolge auf beiden Zeitachsen eingehen.

Wenn eine Korrektur mit einer früheren Gültigkeits- oder Systemzeit als bereits verarbeitete Daten eingeht, schreibt die Engine den betroffenen Verlauf neu, anstatt ihn einfach nur hinten anzuhängen. Keine manuell geschriebene Logik – deklarieren Sie einfach die beiden Sequenzierungsspalten, und die Engine pflegt beide Intervalle. Dies funktioniert gleichermaßen für Dimensionstabellen wie Symbol-Stammdaten als auch für Faktentabellen wie Handelsverläufe oder Sensorwerte, die eine strenge Revisionssicherheit erfordern. So sieht das Ganze im Vergleich zu den FINRA CAT-Referenzdaten aus:

Beachten Sie, dass die genaue SQL-Klausel STORED AS BITEMPORAL lautet, nicht STORED AS SCD TYPE BITEMPORAL, und dass sie sowohl SEQUENCE BY als auch SYSTEM SEQUENCE BY erfordert. Angenommen, das Kennzeichen für die Meldepflicht von Acme ändert sich am 1. Januar (Gültigkeitszeit), aber der Feed empfängt diese Änderung erst am 5. Januar (Systemzeit). Am 8. Januar geht dann eine rückdatierte Korrektur ein, die besagt, dass die tatsächliche Änderung am 1. Januar stattfand, jedoch mit einem anderen Wert. Bitemporales AUTO CDC kann beide Fragen beantworten:

Am 3. Januar liefert die erste Abfrage kein Ergebnis – die korrekte, revisionssichere Antwort darauf, was das System zu diesem Zeitpunkt anzeigte. Die zweite Abfrage, die heute ausgeführt wird, spiegelt die korrigierte Wahrheit wider. Zwei Uhren, zwei Antworten, beide richtig. Sequenzierungsspalten müssen sortierbare Typen sein und dürfen keine NULL-Werte enthalten. Die Funktion läuft auf Serverless SDP oder den Produkt-Editionen Pro/Advanced und befindet sich derzeit in der Beta-Phase. Heften Sie die Pipeline daher an den Channel an: PREVIEW.

Mehr als nur Time Travel: Reproduzierbares ML, das VACUUM übersteht

Wenn ein Modell auf Referenz- oder Feature-Daten trainiert wird, bedeutet Reproduzierbarkeit, dass man Monate später bei einer Überprüfung oder einem Audit genau den Datensatz rekonstruieren kann, den das Modell verwendet hat. Der erste Impuls ist oft, das Time Travel von Delta Lake zu nutzen, aber das ist eine Eigenschaft des Dateiverlaufs der Tabelle, kein dauerhafter Datensatz. VACUUM löscht dauerhaft Datendateien, auf die neuere Versionen nicht mehr verweisen. Nach Ablauf des standardmäßigen 7-tägigen Aufbewahrungsfensters kann ein zum Trainingszeitpunkt protokolliertes TIMESTAMP AS OF unbemerkt nicht mehr aufgelöst werden. Eine bitemporale Tabelle speichert diesen Verlauf als Daten, nicht als Dateiversionen. VACUUM und OPTIMIZE komprimieren Dateien, rühren den logischen Verlauf jedoch nicht an, sodass jede frühere Business- oder Systemversion weiterhin als abfragbare Zeile existiert. Es gibt zwei Möglichkeiten, wie Sie hierdurch Reproduzierbarkeit erzielen können: Protokollieren Sie zwei Zeitpunkte (Gültigkeits- und Systemzeit) als MLflow-Parameter und heften Sie die Trainingsabfrage an diesen Zustand an:

Oder, falls die Tabelle eine aktuelle Ansicht bereitstellt, protokollieren Sie einen einzelnen Systemzeitpunkt beim Training und rekonstruieren Sie diesen später mit einer Systemzeit-Abfrage zu diesem Zeitstempel:

In jedem Fall besteht die Vereinbarung zur Reproduzierbarkeit aus einigen Zeitstempeln im MLflow-Run. Da der bitemporale Verlauf als Zeilen gespeichert wird, bleibt diese Vereinbarung auch dann bestehen, wenn VACUUM die zugrunde liegenden Dateien bereinigt hat.

Partielle Updates für AutoCDC sind jetzt allgemein verfügbar

Nicht alle Change-Data-Capture-Quellen (CDC) geben bei Aktualisierungen vollständige Zeilen aus. Stattdessen senden viele nur die geänderten Felder und stellen alle anderen Spalten als NULL dar. Ohne spezielle Behandlung können diese NULL-Werte versehentlich vorhandene Daten in der Zieltabelle überschreiben. Bisher mussten Kunden eigene Logik entwickeln, um dieses Verhalten zu umgehen. Mit den partiellen Updates für AutoCDC wird dies nun automatisch erledigt.

Partielle Updates erweitern AutoCDC, indem sie es ermöglichen, dass Aktualisierungsereignisse nur eine Teilmenge der Spalten ändern. Für ausgewählte Spalten werden NULL-Werte in einer eingehenden Aktualisierung als „nicht aktualisieren“ interpretiert, anstatt den vorhandenen Wert zu überschreiben.

Dies ist besonders nützlich für CDC-Quellen, die unveränderte Werte weglassen, indem sie NULL ausgeben. Ohne partielle Updates würden diese NULL-Werte vorhandene Daten in der Zieltabelle überschreiben.

Angenommen, die Zieltabelle enthält beispielsweise: (1, 'A', 20)

Ein eingehendes Update-Ereignis enthält: (1, NULL, 30)

Standardmäßig würde AutoCDC die Zeile wie folgt aktualisieren: (1, NULL, 30).

Wenn Partial Updates aktiviert sind, wird der NULL-Wert in name als „bestehenden Wert unverändert lassen“ behandelt, was zu Folgendem führt: (1, 'A', 30).

Das Aktivieren von Partial Updates erfordert lediglich das Hinzufügen eines Parameters zu Ihrer AutoCDC-Definition. Sie können aus drei Möglichkeiten wählen, um anzugeben, welche Spalten als partielle Updates behandelt werden sollen:

  1. eine Spaltenliste, die NULL-Werte ignorieren soll:
    IGNORE NULL UPDATES ON columnList
  2. eine Spaltenliste, die NULL-Werte NICHT ignorieren soll:
    IGNORE NULL UPDATES ON * EXCEPT (columnList)
  3. ein Quellspaltenname, der für jede Zeile unterschiedlich sein kann:
    COLUMNS TO UPDATE

Vollständige Syntax, Beispiele und Anleitungen zur Verwendung finden Sie in der Dokumentation zum Anwenden von Partial Updates.

Wir engagieren uns weiterhin für Open Source

Spark Declarative Pipelines ist Open Source, daher sollte es auch der am häufigsten verwendete Flow-Typ sein. Wir beginnen damit, die Python-API für AUTO CDC Typ 1 zu Apache Spark 4.2 beizutragen.

Wir haben diesen Beitrag so geleistet, wie sich auch der Rest von Spark entwickelt: als eine Reihe von geprüften Vorschlägen und Pull Requests, nicht als einmalige Code-Übergabe (siehe SPIP und SPARK-56249). Die Korrektheit bei ungeordneten Daten ist direkt integriert: Eine kleine Hilfstabelle verfolgt den Status von früh eintreffenden Ereignissen wie Delete Tombstones, wiederholte Microbatches konvergieren, anstatt das Ziel zu beschädigen, und da sie auf den Streaming- und Tabellenabstraktionen von Spark aufbaut und nicht auf einem Speicherformat, läuft sie sowohl auf Delta Lake als auch auf Apache Iceberg.

Was als Nächstes in der Open-Source-Community ansteht:

  • Funktionen des nächsten Releases: Wir haben die SQL-Schnittstelle (CREATE FLOW ... AS AUTO CDC INTO) bereits in den Master-Branch gemergt, was im nächsten Release von Apache Spark enthalten sein wird.
  • Erweiterte Pipeline-Semantik: Die Entwicklung für das vollständige Verlaufshandling von SCD Typ 2, native Changelog-Eingaben und die Unterstützung von Partial Updates läuft bereits, um zu verhindern, dass NULL-Werte Zieldaten überschreiben.
  • Zuverlässigkeit und Tests: Wir fügen „Apply-as-Truncate“-Funktionen hinzu und erweitern gleichzeitig unsere automatisierten Test-Suites für ungeordnete Daten und idempotente Wiederholungsversuche.

Erste Schritte

Ganz gleich, ob Sie bitemporale Compliance implementieren, Partial Updates einrichten oder Open-Source-AutoCDC in Apache Spark erkunden möchten – werfen Sie einen Blick auf die folgenden Ressourcen, um loszulegen:

(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag

Erhalten Sie die neuesten Beiträge in Ihrem Posteingang

Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.