This article is also available in English
Im modernen Data Engineering ist ein Wandel weg von der Entwicklung monolithischer Datenpipelines und hin zu modularen Datenprodukten eingetreten.
Ein Datenprodukt ist das zu liefernde Ergebnis, das alles in Verbindung mit einem Geschäftskonzept zur Erfüllung der Bedürfnisse eines Datenverbrauchers enthält:
- Tabellen zur Speicherung der Daten
- Code zur Umwandlung von Daten
- Tests, um zu überprüfen und zu überwachen, ob die Daten korrekt sind
- Ausgabe-Ports, um den Zugriff auf die Daten zu ermöglichen
- Eingabe-Ports, um Daten aus Quellsystemen aufzunehmen oder auf andere Datenprodukte zuzugreifen
- Data Contracts zur Beschreibung der API
- Dokumentation
- Meta-Informationen wie etwa Eigentum
Ein Datenprodukt wird üblicherweise in einem Git-Datenspeicher verwaltet. Databricks ist eine der beliebtesten modernen Datenplattformen. Wie können wir ein professionelles Datenprodukt mit Databricks entwickeln?
In diesem Artikel werden wir Data Contracts und die neuen Databricks Asset Bundles nutzen, die hervorragend miteinander kombiniert werden können, um Datenprodukte zu implementieren. Der gesamte Quellcode dieses Beispielprojekts ist auf GitHub verfügbar.
Definieren des Data Contract
Bevor wir mit der Implementierung beginnen, erörtern und definieren wir die geschäftlichen Anforderungen. Was benötigt unser Datenverbraucher von uns, wie stellt sich sein Use Case dar, was erwartet er als Datenmodell. Und wir müssen sicherstellen, dass wir von derselben Semantik und denselben Qualitätserwartungen ausgehen und dieselben Service-Level erwarten.
Wir nennen diesen Ansatz Contract-First. Wir beginnen mit der Gestaltung der Schnittstelle des gelieferten Datenmodells und seiner Metadaten als Data Contract. Wir nutzen den Data Contract, um die Implementierung voranzutreiben.
In unserem Beispiel möchte der Geschäftsführer eines E-Commerce-Unternehmens wissen, ob ein Problem mit Artikeln besteht, die über einen längeren Zeitraum nicht verkauft werden, d. h. Artikel ohne Umsatz in den letzten drei Monaten – sogenannte Ladenhüter.
Wir definieren in Zusammenarbeit mit dem Datenverbraucher einen Data Contract als YAML unter Verwendung der Data Contract Specification.
Der Datensatz wird alle derzeit im Bestand befindlichen Artikel beinhalten und umfasst last_sale_timestamp
, das für den Geschäftsführer relevanteste Attribut. Der Geschäftsführer kann in seinem BI-Tool (wie etwa PowerBI, Redash etc.) nach Artikeln mit einem last_sale_timestamp
älter als drei Monate filtern. Bedingungs- und Service-Level-Attribute weisen darauf hin, dass der Datensatz täglich um Mitternacht aktualisiert wird.
Erstellen des Databricks Asset Bundle
Nun ist es an der Zeit, ein Datenprodukt zu entwickeln, das diesen Data Contract implementiert. Databricks fügte vor Kurzem das Konzept der Databricks Asset Bundles hinzu, die sich perfekt eignen, um Datenprodukte zu strukturieren und zu entwickeln. Zum Zeitpunkt der Abfassung im März 2024 sind diese öffentlich als Vorschauversion verfügbar, d. h., sie sind bereit für die Nutzung in der Produktion.
Databricks Asset Bundles beinhalten alle Infrastruktur- und Codedateien, um tatsächlich Daten in Databricks umzuwandeln:
- Infrastruktur-Ressourcen
- Arbeitsbereich-Konfiguration
- Quelldateien wie Notebooks und Python-Skripte
- Unit-Tests
Die Databricks CLI bündelt diese Assets und setzt sie in der Databricks-Plattform ein, intern wird Terraform verwendet. Asset Bundles sind gut in die Databricks-Plattform integriert, d. h., es ist nicht möglich, Code oder Aufträge direkt in Databricks zu bearbeiten, was eine strenge Versionskontrolle der gesamten Code- und Pipeline-Konfiguration ermöglicht.
Bundles sind extrem nützlich, wenn mehrere Umgebungen bestehen, wie etwa Entwicklung, Staging und Produktion. Sie können dasselbe Bundle für mehrere Ziele mit verschiedenen Konfigurationen einsetzen.
Um ein Bundle zu erstellen, muss es in einem neuen Bundle initiiert werden:
Wir verwenden diese Konfiguration:
- Zu verwendete Vorlage: default-python
- Eindeutiger Name für dieses Projekt: stock_last_sales
- Einfügen eines Stub-(Sample-)Notebooks in
stock_last_sales/src
: yes - Einfügen einer Stub (Sample) Delta Live Tables Pipeline in
stock_last_sales/src
: no - Einfügen eines Stub-(Sample-)Python-Pakets in
stock_last_sales/src
: yes
Werfen wir hinsichtlich der Bundle-Struktur einen kurzen Blick auf die relevantesten Dateien:
- databricks.yml Die Bundle-Konfiguration und Einsatzziele
- src/ Der Ordner für den Umwandlungscode
- tests/ Der Ordner für die Platzierung der Unit-Tests
- resources/ Die Auftragsdefinition für die Definition des Workflows
Anmerkung: Wir empfehlen, ein internes Bundle beizubehalten, das die Namenskonventionen, allgemeinen Vorschriften, Best Practices und Integrationen des Unternehmens enthält.
Mit Asset Bundles können wir unseren Code auch lokal in unserer bevorzugten IDE schreiben, wie etwa VS Code (unter Verwendung der Databricks-Erweiterung für Visual Studio Code), PyCharm oder IntelliJ IDEA (unter Verwendung von Databricks Connect).
Um eine lokale Python-Umgebung einzurichten, können wir venv verwenden und die Entwicklungsabhängigkeiten installieren:
Generierung der Unity-Catalog-Tabelle
Wie organisieren wir die Daten für unser Datenprodukt? In diesem Beispiel verwenden wir Unity Catalog, um Speicher als verwaltete Tabellen zu handhaben. Auf Isolationsebene entscheiden wir, dass ein Datenprodukt ein Schema in Unity Catalog repräsentieren könnte.
Wir können den Data Contract YAML nutzen, um Infrastruktur-Code zu generieren:
Das Modell definiert die Tabellenstruktur des Zieldatenmodells. Mit dem Data Contract CLI tool, können wir den SQL-DDL-Code für die Anweisung CREATE TABLE generieren.
Das Data Contract CLI tool ist ebenfalls als eine Python Library datacontract-cli verfügbar. Wir fügen es zu requirements-dev.txt hinzu und verwenden es direkt in einem Databricks-Notebook, um die Tabelle in Unity Catalog zu erstellen:
Die Unity-Catalog-Tabelle ist eine verwaltete Tabelle, die intern zur effizienten Speicherung das Delta-Format nutzt.
Entwickeln des Umwandlungscodes
Jetzt schreiben wir die Hauptumwandlungslogik. Mit Python-basierten Databricks Asset Bundles können wir unsere Daten-Pipelines entwickeln als:
- Databricks-Notebooks,
- Delta-Live-Tabellen oder
- Python-Dateien
In diesem Datenprodukt werden wir einfache Python-Dateien für unsere Hauptumwandlungslogik schreiben, die als Wheel-Pakete eingesetzt werden.
Unsere Umwandlung nimmt alle verfügbaren Bestände, die wir von einem Eingabe-Port wie etwa dem Betriebssystem erhalten, das die aktuellen Bestandsdaten verwaltet, und fügt den Datenframe mit dem Zeitstempel des letzten Verkaufs für jede SKU per Left-Join hinzu. Die Umsatzinformationen sind ebenfalls ein Eingabe-Port, z. B. ein weiteres vorgelagertes Datenprodukt, das von dem Kassenteam bereitgestellt wird. Wir speichern den resultierenden Datenframe in der zuvor generierten Tabellenstruktur.
Dank dieser Option bleibt der Code wiederverwendbar, ist leicht mit Unit-Tests zu testen und wir können ihn auf unseren lokalen Computern ausführen. Als professionelle Datentechniker stellen wir sicher, dass die Funktion calculate_last_sales
wie erwartet ausgeführt wird, indem sie gute Unit-Tests schreibt.
Wir aktualisieren die Auftragskonfiguration, um den Python-Code als python_wheel_task
auszuführen, und konfigurieren das Steuerprogramm und den entsprechenden Rechencluster.
Wenn wir uns sicher sind, können wir das Bundle in unseren Databricks-dev-Instanzen (derzeit manuell) einsetzen:
Wir lösen eine manuelle Ausführung unseres Workflows aus:
In Databricks können wir sehen, dass der Workflow erfolgreich ausgeführt wurde:
Die Daten sind jetzt in der zuvor erstellten Tabelle enthalten.
Testen des Data Contract
Unsere Aufgabe ist noch nicht ganz beendet. Woher wissen wir, dass die Daten korrekt sind? Während die Unit-Tests uns Sicherheit hinsichtlich des Umwandlungscodes geben, benötigen wir auch eine Abnahmeprüfung, um zu überprüfen, ob wir den vereinbarten Data Contract korrekt implementiert haben.
Für diese Prüfung können wir das Data Contract CLI tool verwenden:
Das datacontract Tool verwendet alle Schema- und Formatinformationen aus _model_, den Qualitätsattributen und den Metadaten und vergleicht diese mit dem tatsächlichen Datensatz. Es liest die Verbindungsdetails aus dem Serverabschnitt und verbindet sich mit Databricks, führt alle Prüfungen aus und bietet eine umfassende Übersicht.
Wir möchten diesen Test mit jeder Pipelineausführung durchführen und erstellen daher erneut eine Notebook-Aufgabe für den Test:
Einsatz mit CI/CD
Für einen automatischen Test wird das Asset Bundle auf Databricks bereitgestellt, und nach der einmaligen Ausführung des Auftrags richten wir eine CI/CD-Pipeline in GitHub unter Verwendung einer GitHub Aktion ein.
Jedes Mal, wenn wir den Code aktualisieren, wird das Asset Bundle automatisch auf Databricks bereitgestellt.
Metadaten veröffentlichen
Damit andere die Datenprodukte finden, verstehen und ihnen vertrauen können, wollen wir sie in einem Datenproduktverzeichnis registrieren.
In diesem Beispiel verwenden wir den Data Mesh Manager – eine Plattform für das Registrieren, Verwalten und Entdecken von Datenprodukten, Data Contracts und globalen Vorschriften.
Wir erstellen erneut eine Notebook-Aufgabe (oder Python-Codeaufgabe), um die Metadaten im Data Mesh Manager zu veröffentlichen, und fügen dann die Aufgabe zu unserem Workflow hinzu. Wir können Databricks Secrets verwenden, um den API-Schlüssel in Databricks bereitzustellen.
Zusammenfassung
Jetzt kann sich der Geschäftsführer über ein BI-Tool (wie etwa PowerBI, Tableau, Redash oder in Databricks) mit dieser Tabelle verbinden und seine Frage bezüglich des Artikels beantworten.
Databricks Asset Bundles sind perfekt geeignet, um professionelle Datenprodukte auf Databricks zu entwickeln, da es alle Ressourcen und Konfigurationen (Code, Tests, Speicher, Berechnen, Steuerungsprogramm, Metadaten etc.) bündelt, die benötigt werden, um den Datenverbrauchern Datensätze in hoher Qualität zu liefern.
Es ist einfach, Data Contracts zur Definition der Anforderungen und die Data Contract CLI zur Automatisierung von Abnahmeprüfungen zu integrieren.
Der Quellcode für das Beispielprojekt ist auf GitHub verfügbar.