Wie wir unsere Marketing-Datenpipelines mit dlt erfolgreich skaliert haben
Diese Blogpost Serie richtet sich an Data Engineers, Analytics Engineers und technische Marketeers, die mit grundlegenden ETL-Konzepten, Python sowie Tools wie Airflow oder dbt vertraut sind. Tiefgehende Expertise in einer bestimmten Plattform ist nicht nötig, aber ein grundlegendes Verständnis davon, wie API-Datenintegration, Orchestrierung und Cloud Data Warehouses zusammenspielen, hilft, das Beste aus diesem Beitrag mitzunehmen.
Wer mit Marketing-Daten arbeitet, jongliert mit einer wachsenden Zahl von APIs, sich ständig ändernden Schemas und zum Teil auch hohen Kosten. In einem unserer internen Projekte haben wir die Datenintegration mit Hunderten von eigens erstellten Airflow-DAGs (Directed Acyclic Graph) gesteuert. Jeder davon war individuell geschrieben, oft mit doppelter Logik in den Skripten. Das Durchforsten glich einer Reise durch wechselnde Code-Stile und Namenskonventionen, mit lückenhafter oder veralteter Dokumentation. Es funktionierte, bis es eben nicht mehr funktionierte. Die Wartungskosten wurden zu einer Belastung, ganz zu schweigen von der Skalierung oder Erweiterung, und das Onboarding glich einem Sprung in ein Labyrinth.
Unsere Extraktionsschicht mussten wir nicht neu aufbauen, denn die Logik dort war stabil. Was wir brauchten, war eine bessere Lösung für die Ladeschicht unseres Data Stacks: Daten nach S3, nach Snowflake bringen und Standard-Transformationen anwenden. Also haben wir einen Wechsel vollzogen. Wir haben dlt (Data Load Tool) eingeführt – eine Open-Source-Python-Bibliothek, die unsere Art der Datenintegration, -bereinigung und das Laden erheblich vereinfachte.
Im ersten Teil unserer Blog-Serie berichten wir darüber, wie wir dlt in unseren Marketing Data Stack integriert haben und was wir dabei gelernt haben. Wir zeigen auf, wie wir die Datenintegration skalieren konnten, ohne die Komplexität zu erhöhen. Später gehen wir tiefer auf die Herausforderungen ein, die wir beim Einsatz von dlt für unseren speziellen Use Case erlebt haben.
Das Problem mit Legacy-DAGs
Vor dlt folgten unsere Integrationspipelines einem Muster, das vielen Data-Engineering-Teams bekannt vorkommen dürfte: zahlreiche individuelle Python-Skripte, orchestriert über Airflow. Jede neue Marketing-API – Adobe, Meta, LinkedIn usw. – und jedes Konto bekam einen eigenen DAG, eigene Schema-Definitionen und oft eigene Besonderheiten, die direkt in den Code eingebaut waren.
Unser ursprüngliches Setup war organisch gewachsen: Daten aus einer API extrahieren, Dateien in S3 ablegen, mit SQL-Statements in Snowflake laden. Jeder DAG wiederholte dieselbe S3-Staging-Logik, Tabellen-Erstellungsbefehle und manchmal sogar Transformationen.
Das führte zu folgenden Herausforderungen:
- Duplizierte und überlappende DAGs im überfrachteten Airflow, mit uneinheitlichen Namen und Metadaten.
- Hart codierte Schemas und fragile Transformationen machten Updates fehleranfällig, oft mussten ganze DAGs erneut laufen.
- Uneinheitliches Logging, Retries und Normalisierung verursachten zusätzlichen Aufwand im Betrieb.
- Langsames Onboarding neuer Teammitglieder: Copy-Paste-Logik, alte Annahmen, verstreute Schema-Definitionen.
- Inkrementelle Loads erforderten manuelles Handling, was Komplexität und Wartungsaufwand erhöhte.
Mit der Zahl der Datensätze wuchs auch der Aufwand für den Betrieb, und die Folgen dieses Musters wurden zunehmend schwierig:
- Das Onboarding einer neuen API-Quelle dauerte Tage, selbst bei ähnlichen JSON-Endpunkten.
- Das Pflegen von Schemas über viele DAGs hinweg wurde fehleranfällig, besonders wenn Anbieter ihre Felder oder verschachtelten Strukturen änderten.
- Debugging erforderte das Nachvollziehen einzelner Skripte, die alle leicht unterschiedlich mit Edge Cases, Retries oder Logging umgingen.
Mit der Zeit summierten sich einige Ineffizienzen. Mehr Zeit floss in die Wartung als in die Entwicklung neuer Fähigkeiten. Die Dokumentation blieb zurück, und es wurde schwieriger, neue Teammitglieder einzuarbeiten. Selbst wenn wir Muster teilweise standardisiert hatten, fehlten echte Wiederverwendbarkeit und Abstraktion.
Deshalb wollten wir nicht nur eine neue Methode, um Daten zu verschieben, sondern ein Framework, das folgendes leisten konnte:
- Schema-Drift elegant handhaben,
- Boilerplate-Code reduzieren,
- Pipelines konfigurieren statt umprogrammieren,
- Mit dem Team skalieren, wenn neue Daten verwendet werden.
An dieser Stelle kam dlt ins Spiel.
Warum wir uns für dlt entschieden haben
dlt erfüllte für uns von Beginn an mehrere zentrale Kriterien:
- Open Source und Python-nativ: Wir konnten es direkt in unseren bestehenden Stack und unsere Workflows integrieren, ohne große Umschreibungen.
- Automatische Schema-Erkennung, -Entwicklung und -Normalisierung – inklusive verschachtelter JSON-Strukturen, die bei Marketing-APIs häufig vorkommen.
- Trennung von Ingestion-Logik und Orchestrierung: Wir konnten uns auf die Pipeline-Logik konzentrieren statt auf Scheduling.
- Saubere Integration mit Snowflake und Unterstützung von S3 als Staging Layer – perfekt für unsere AWS-Architektur.
- Konfigurationsgetrieben (TOML, Umgebungsvariablen): Quelle-spezifische Logik lässt sich ohne doppelten Code verwalten.
- Eingebaute Unterstützung für Lineage, Benachrichtigungen, Retries und inkrementelle Loads – weniger Custom Code nötig.
dlt traf für uns genau die richtige Balance zwischen Kontrolle und Komfort.
Ein weiterer wichtiger Faktor war die Flexibilität beim Deployment. Da dlt einfach Python ist, konnten wir es mit der TaskFlow API direkt in Airflow einsetzen. Das bedeutete:
- Keine neue Infrastruktur erforderlich.
- Minimaler Schulungsaufwand für Entwickler:innen.
- Einfache Versionskontrolle und Promotion über unsere bestehenden CI/CD-Workflows.
Wir schätzten auch die aktive Open-Source-Community hinter dlt. Über den Slack-Channel bekamen wir schnell Unterstützung, und seit wir dlt einsetzen, ist die Dokumentation erheblich gewachsen.
Wie wir dlt implementiert haben
Nachdem wir uns für dlt entschieden hatten, konzentrierten wir uns auf eine Architektur, die Modularität, Wiederverwendbarkeit und Skalierbarkeit ausbalanciert – und gleichzeitig auf Tools basiert, die unser Team bereits kannte: Airflow, S3 und Snowflake.
Wir haben unsere Pipelines mit einer klaren Trennung der Verantwortlichkeiten neu gestaltet:
- Extraktion über eigene Python-Skripte und API-Calls
- Staging über Amazon S3
- Laden & leichte Transformationen über dlt
- Kerntransformationen in dbt Cloud (Staging-, Intermediate- und Mart-Modelle)
- Verwaltung von Zugangsdaten über AWS Parameter Store
Das folgende Diagramm zeigt, wie die Teile zusammenpassen:
Zentrale Implementierungsdetails für dlt
- Datenextraktion: Python-Skripte und dlt-Sources holen Rohdaten und speichern CSV/JSON in einer konsistenten S3-Ordnerstruktur.
- S3-Staging: dlt liest aus diesen Buckets, standardisiert Formate und bereitet die Daten für Snowflake auf.
- dlt-Ingestion: dlt konvertiert Dateien in Parquet, verarbeitet Schema-Drift automatisch und lädt die Daten in die Raw-Layer von Snowflake.
- Leichte Transformationen: dlt führt nur minimale Umbenennungen, Typanpassungen und Standardisierungen durch, um Komplexität zu vermeiden.
- dbt Cloud für Transformationen: Das „Heavy Lifting“ (Joins, Data Quality Checks, Marts) erfolgt downstream in dbt, wodurch die Business-Logik zentral bleibt.
Umgang mit Secrets
Die Verwaltung von Zugangsdaten war einer der kniffligeren Aspekte bei der Integration von dlt in unseren Stack. Der Standardansatz von dlt nutzt .toml-Konfigurationsdateien für Secrets, aber wir stießen schnell auf die Zeichenlimits des AWS Parameter Store – einfach aufgrund der Vielzahl an Marketing-Quellen.
Anstatt den Parameter Store aufzugeben, haben wir einen hybriden Ansatz gewählt:
- Zugangsdaten bleiben als individuelle sichere Variablen im AWS Parameter Store gespeichert.
- Zur Laufzeit erzeugen wir dynamisch die .toml-Dateien, die dlt erwartet.
- So bleiben Secrets zentralisiert, sicher und konsistent mit der restlichen Infrastruktur.
Damit konnten wir Secrets zentral, sicher und konsistent mit der restlichen Infrastruktur verwalten – und gleichzeitig dlt zufriedenstellen.
Ergebnisse der Einführung von dlt
Die Einführung von dlt hat grundlegend verändert, wie wir Marketing-Datenpipelines steuern. Durch den Wechsel von handgeschriebener Ingestion-Logik zu einem standardisierten, konfigurationsgetriebenen Ansatz konnten wir sofortige Vorteile feststellen:
- Schnelleres Onboarding: Das Hinzufügen einer neuen API-Quelle dauert nur noch einen Bruchteil der Zeit.
- Weniger Redundanz: Gemeinsame Lade-Logik hat den Wartungsaufwand erheblich reduziert.
- Höhere Zuverlässigkeit: Automatisches Schema-Handling, Retries und Logging führen zu deutlich weniger fehlerhaften Loads.
Diese Veränderung hat Data Engineering-Kapazitäten freigesetzt, mit denen wir uns auf wichtige Transformationen in dbt konzentrieren konnten, statt Ressourcen mit Debugging von Ingestion-Problemen zu binden.
Tipps für Teams, die dlt einführen möchten
Wenn Sie dlt für Ihre Datenpipelines in Betracht ziehen, lautet unser wichtigster Tipp: Starten Sie einfach! Beginnen Sie mit einer kleinen, risikoarmen Pipeline, um zu verstehen, wie Konfiguration, Schema-Handling und Retries in Ihrer Umgebung funktionieren, bevor Sie skalieren.
Einige Tipps aus unserer Erfahrung:
- Nutzen Sie Staging: S3 als Zwischenschicht verschaffte uns mehr Kontrolle und Transparenz über die geladenen Daten.
- Transformationen in dlt minimal halten: Wir haben festgestellt, dass dlt am besten funktioniert, wenn es nur leichte Transformationen übernimmt und dbt die komplexen Aufgaben erledigt.
- Konfigurationen früh planen: Zentrale Konfigurationen sind mächtig. Planen Sie frühzeitig, wie Sie Credentials, Ziele und Umgebungen verwalten.
- Rechnen Sie mit Trial-and-Error: Besonders bei mehreren Zielen oder komplexer Orchestrierung werden Anpassungen nötig sein.
Für uns hat sich die Lernkurve gelohnt. Sobald die Grundlagen standen, konnten wir mit dlt schneller arbeiten, Ingestion standardisieren und mehr Zeit in Analytics statt in Boilerplate-Code investieren.
Wie geht es weiter?
In diesem Beitrag ging es darum, warum wir dlt eingeführt haben und wie wir es in unseren Data Stack integriert haben, um Loading und leichte Transformationen zu vereinfachen. Doch wie bei jeder Migration gab es auch bei uns spezielle Herausforderungen.
In kommenden Beiträgen gehen wir tiefer ein auf Themen wie:
- Secrets im großen Maßstab managen: Wie wir Hunderte von Zugangsdaten sicher über AWS Parameter Store verwalten und gleichzeitig dlt mit seinem .toml-Modell zufriedenstellen.
- Multi-Pipeline-Concurrency: Unser Ansatz, Dutzende von dlt-Pipelines parallel laufen zu lassen, Konflikte zwischen Konfigurationen zu lösen und zwei Snowflake-Ziele zu orchestrieren.
- Schema-Persistenz & -Evolution: Lessons Learned beim Umgang mit Schema-Entwicklung (und -Rückschritten) in dlt.
Wenn Sie dlt in Betracht ziehen oder Ihre eigenen Datenpipelines modernisieren wollen, bleiben Sie dran: Wir teilen noch mehr zu den Herausforderungen, die wir bei der Implementierung erlebt haben und wie wir sie gelöst haben.
Und natürlich greifen wir Ihnen auch gerne unter die Arme, falls Sie hierzu eine Erstberatung oder Unterstützung benötigen!