Domain-Driven Datenarchitektur
Wir arbeiten seit zwei Jahren am Aufbau eines Computercluster für das Fraunhofer ISE.
Dabei wurde von uns häufig erwartet, dass wir diesen zentralisiert, monolithisch und domänenunabhängig aufbauen, also als sog. Data Lake.
Die größte Herausforderung besteht nicht darin, einen Datensee zu erstellen, sondern die sich daraus ergebenden Chancen zu nutzen.
– Sean Martin, CTO Cambridge Semantics
Wir konnten jedoch bereits früher zusammen mit anderen Kunden erkennen, dass diese Chancen kaum genutzt werden konnten. Hier deswegen zunächst ein kurzer Überblick über frühere Architektur-Generationen:
Historie
Generation: Enterprise Data Warehouse (EDW)
Vor einem Jahrzehnt waren Daten meist ein Synonym für relationale Datenbanken. Meist führte dies jedoch zu hohen technischen Schulden in Form von tausenden nicht zu überarbeitenden ETL (extract, transform, load)-Jobs, die nur eine kleine Gruppe von Fachleuten versteht. Damit blieben jedoch die erhofften positiven Auswirkungen unerfüllt.
Generation: Big-Data-Ökosystem mit einem Data Lake
Jetzt können Daten eine erstaunliche Vielfalt von Formen annehmen einschließlich NoSQL, Zeitreihen und SQL. Dies ist auf den Wunsch zurückzuführen, immer schneller auf immer größere, vielfältigere und schnellere Datenquellen zu reagieren. Forscher werden jedoch mit dem Verstehen unterschiedlicher Arten der Datenhaltung vor zusätzliche Herausforderungen gestellt. Aktuell bekommen wir also zusätzliche Möglichkeiten, ohne dass jedoch die grundlegenden Probleme der vorgehenden Generation gelöst worden wären. Diese Ökosysteme mit lange laufenden Batch-Jobs werden mit all ihren Auswirkungen meist nur von hochspezialisierten Fachleuten verstanden. Zwar führte dies theoretisch zu einer Fülle von möglichen Analysen und Simulationen, diese konnten aber wegen ihres Umfangs und ihrer Komplexität praktisch nur selten realisiert werden.
CockRoachDB und Spanner bieten darüberhinaus globale Konsistenz und Event stream processing (ESP) mit Abfragemöglichkeiten für aggregierte Log-Dateien.
Ein Nachteil dieses Ansatzes besteht jedoch darin, dass er eher an low-level Database Events als an Geschäftsereignisse auf höherer Ebene gebunden ist, die für uns die Grundlage einer ereignisorientierten Architektur sein sollte – Ereignisse sollten in ihren Domänen explizit erfasst werden oder Statusübergänge sollten nicht impizit erschlossen werden müssen.
Beiden Generationen sind jedoch die folgenden Architekturfehler gemeinsam:
- zentral und monolithisch
- sequenzierte Pipeline
- spezialisiertes Eigentum
Ad 1. Zentral und monolithisch
Alle zugänglichen Daten wurden erfasst und dem ETL (extract, transform, load)-Dreischritt unterworfen:
Extract
Möglichst alle Daten wurden erfasst, unabhängig davon, ob sie für eine spezifische Fachdomäne benötigt wurden oder nicht.
Transform
Die Transformation der Daten erfolgte üblicherweise ebenfalls nicht in Hinblick auf die konkreten Erfordernisse sondern vielmehr in Hinblick auf eine möglichst universelle Verwendbarkeit. Häufig wurden die Daten auch noch mit Informationen aus anderen Datenquellen angereichert um prinzipiell noch umfassendere Analysen machen zu können.
Load
In diesem Schritt wurde darauf geschaut, dass die Daten für eine Vielzahl von Fachdomänen über die gewünschten Protokolle bereitgestellt werden können.
Während wir bei der Anwendungsentwicklung in den letzten Jahren darauf achteten, dass das Design spezifisch für die jeweilige Domäne ist und auch nur in diesem spezifischen Kontext funktionieren muss, wurde Domain Driven Design bei den Datenplattformen weitgehend ignoriert. Dies führte dann zu den bekannten Problemen:
- Die Aufwände, diese domänenunspezifischen Daten zu harmonisieren, nahmen zu.
- In vielen Fällen war zu sehen, dass die Integration neuer Datenquellen verzögert oder blockiert wurde, weil sie nicht in das universelle Schema passen wollen.
Die von uns vorgeschlagene Alternative wird nicht zu fragmentierten, isolierten und domänenorientierten Daten führen, die schwer zu entdecken sind sowie spezifisches Wissen zum Verstehen und verarbeiten benötigen. Dies wären dann auch nur wieder fragmentierte Data Warehouses, wie sie sich häufig zur Umgehung der oben genannten Probleme angestaut haben und die nun als technische Schulden weitere Innovationen behindern.
Ad 2: Sequenzierte Pipeline
Der ETL (extract, transform, load)-Dreischritt offenbart jedoch noch weitere Schwierigkeiten, die sich aus der sequentiellen Aufteilung der Funktionen ergeben. Die Motivation für das Sequenzieren der Datenverarbeitung lag in der bestehenden Arbeitsteilung der Forschungsteams.
Organisationen, die Systeme entwerfen, … sind auf Entwürfe festgelegt, welche die Kommunikationsstrukturen dieser Organisationen abbilden.
– Melvyn E. Conway: Conway’s Law, 1967
Obwohl diese Gliederung ein gewisses Maß an Skalierung zu bietet scheint, da Teams verschiedenen Phasen der Verarbeitungspipeline zugewiesen werden, kommt dieser Effekt jedoch meist nicht zum Tragen, da bei neuen Features meist alle Sequenzen der Pipeline überarbeitet werden müssen.
So müssten z.B. für die Ergänzung der Strom-Ex- und Import-Daten um geplante und ungeplante Kraftwerksausfälle alle drei ETL-Bereiche angepasst werden.
Ad 3: Spezialisiertes Eigentum
Das dritte Problem hängt damit zusammen, wie die Teams strukturiert sind, die die Plattform erstellen und betreiben. Meist sind diese Teams isoliert von denjenigen, die diese Plattform für ihre Analysen und Simulationen nutzen. Sie erlangen also meist keine Kenntnis von den Datenquellen und deren Verwendung; sie sollen nur betriebliche und analytische Anforderungen erfüllen, ohne jedoch jemals ein klares Verständnis für eine konkrete Anwendung der Daten zu erhalten.
Die nächste Generation von Datenplattformen
Aus den oben angesprochenen Problemen wird deutlich, dass ein Paradigmenwechsel erforderlich ist. Ein Paradigmenwechsel, der in anderen IT-Bereichen bereits stattgefunden hat und dort bereits die Erprobungsphase verlassen hat: Domain-Driven Architecture, Self-Service-Plattforms und Product Thinking führen zu ubiquitous computing in einem vermaschten Netz (engl. Mesh).
Domain-Driven Architektur
Domänenorientierte Aufteilung und Eigentum der Datensätze
Eric Evans Buch Domain-Driven Design hat nicht nur die moderne Software-Architektur tiefgreifend beeinflusst, sondern auch die Organisationsentwicklung: Nicht nur wurden monolithische Systeme in Microservices zerlegt, auch die um Technologieschichten (Datenbank, Anwendungslogik, UI) organisierten Teams wurden umgewandelt in domänenspezifische Teams.
Bei einem solchen dezentralen Datenmanagement ist dann die Herausforderung, wie diese domänenspezifischen Daten gemeinsam genutzt werden können. Dies ist gut in Ben Stopfords Data Dichotomy-Artikel beschrieben.
Um nun eine monolithische Datenplattform zu dezentralisieren, müssen wir auch unsere Einstellung zu Ort und Eigentum dieser Daten überdenken: statt fleißig Daten in unseren eigenen, zentral gelegenen Data Lake zu übernehmen, müssen nun die Fachdomänen selbst für das Hosting dieser Daten sorgen und sie in einfach zu verarbeitender Weise zur Verfügung stellen. Dies kann dann zur Folge haben, dass wir dieselben Daten, jedoch für jede der Fachdomänen unterschiedlich aufbereitet, so auch in verschiedenen Domänen speichern.
Damit verlagert sich der Datenfluss von einem sequenzierten Pipeline-Prozess hin zu einer domänenspezifischen Aufbereitung.
Quelldomän-Datensätze
Einige Domänen richten sich natürlich nach der Herkunft der Datensätze. Meist entstehen diese Datensätze sehr nahe an der Quelle, an der die Daten entstehen. Idealerweise übernehmen die Lieferanten dieser Datensätze auch die Gewähr, dass diese hinreichend integer sind.
Note
Diese Datensätze enthalten meist nur Rohdaten, die zum Zeitpunkt der Erstellung möglichst genau wiedergeben und nicht für einen bestimmten Konsumenten angepasst oder modelliert sind.
Verbraucherorientierte und gemeinsam genutzte Datensätze
Einige Domänen bestimmen sich nicht aus der Herkunft sondern dem Ziel, das erreicht werden soll. Auch ansonsten unterscheiden sich diese Datensätze erheblich von denjenigen der Quelldomäne: Sie werden jedoch transformiert, um einen möglichst einfachen Zugriff darauf zu erlauben. Hier entsteht also eine Pipeline zur Bereinigung, Aufbereitung, Aggregation und Bereitstellung der Daten.
Self-Service-Platforms
Es gibt jedoch nicht nur innerhalb der Domänen von verbraucherorientierten Datensätzen Verarbeitungspipelines, sondern auch bereits bei Quelldomän-Datensätzen: Dort müssen die Daten auf Vollständigkeit überprüft werden und frei von Dubletten sein.
Um die Komplexität solcher Pipelines jedoch so gering wie möglich zu halten, werden sie immer nur innerhalb ihrer eigenen Domäne behandelt. Dort können dann auch Service-Levels für die Daten dieser Domäne definiert werden wie Aktualität, Fehlerraten etc.
Product Thinking
In anderen Bereichen wurden Produkte schon viel früher über Projekte gestellt, s.a. Products over Projects. Zukünftig werden die Teams einer Datendomäne den Forschungsteams ihre Funktionen als APIs zur Verfügung stellen und liefern so einen Baustein für die Schaffung höherer Funktionalitäten und Auftragswerte. Damit ein solches Produkt erfolgreich wird, müssen die Daten folgende Eigenschaften aufweisen:
Ein Datenprodukt muss leicht auffindbar sein
Eine übliche Implementierung besteht in einer Registrierung und einem Datenkatalog aller Datenprodukte mit ihren Metainformationen. Diese zentrale Anlaufstelle ermöglicht Datenkonsumenten, die Datensätze ihres Interesses leicht zu finden.
Jedes Datenprodukt muss eine eindeutige Adresse haben
Diese Adresse muss einer globalen Konvention folgen und anderen Benutzern erleichtern, programmatisch auf diese Daten zuzugreifen. Und auch wenn die zugrundeliegenden Speicher und Datenformate unterschiedlich sind, z.B. Events als Stream von Kafka Topics oder Kolumnen in Apache Parquet, so müssen diese Daten doch einheitlich adressierbar sein um Reibungsverluste beim Auffinden und Zugreifen auf diese Daten gering zu halten.
Die Daten müssen vertrauenswürdig und wahrheitsgemäß sein
Hierfür werden Service-level Objectives (SLOs) definiert und überwacht. Hierfür werden die Daten bereinigt, Dubletten entfernt und automatisiert Integritätstests durchgeführt.
Ebenso sollte die Datenherkunft (engl.: Data Lineage) als Metadaten bereitgestellt werden um die Eignung für spezielle Bedürfnisse ermitteln zu können.
Die SLOs können jedoch zwischen den einzelnen Datenprodukten variieren.
Die Semantik und Syntax sollte leicht zugänglich sein
Datenschemata sind häufig der Ausgangspunkt für die Bereitstellung von Self-Service-Datenbeständen. Daher werden sie üblicherweise zusammen mit Beispieldatensätzen leicht zugänglich veröffentlicht.
Die Daten sollten interoperabel sein
Auch wenn die Daten in einzelnen Fachdomänen verwaltet werden, so ist jedoch erklärtes Ziel, die Daten domänenübergreifend korrelieren zu können. Voraussetzung für effektive Korrelationen sind das Einhalten bestimmter Standards und Harmonisierungsregeln. Dies wird z.B. über die Definition von Feldtypen, die Identifizierung bestimmter Polyseme in verschiedenen Domänen, Adresskonventionen für Datensätze, gemeinsame Metadatenfelder, Event-Formate wie z.B. in der CloudEvents Specification) festgelegt etc.
Der Zugriff auf Produktdatensätze muss sicher sein und sollte einer globalen Zugriffskontrolle unterliegen
Hierfür können Single Sign On und Role Based Access Control verwendet werden.
Vermaschtes Netz
Domain-Driven Architecture, Self-Service-Plattforms und Product Thinking kommen zusammen in einem vermaschten Netz. Einerseits besteht dieses aus verteilten Datenprodukten, die sich an Domänen orientieren und die im Besitz unabhängiger und funktionsübergreifender Teams sind; andererseits nutzen sie eine gemeinsame Dateninfrastruktur mit einer Hosting-Plattform und ETL-Bibliotheken. Darüberhinaus wird die Vereinheitlichung von batch- und streaming-Jobs, z.B. mit Apache Beam, die problemlose Verarbeitung adressierbarer polyglotter Datensätze ermöglichen. Das Beam-Modell basiert auf dem Dataflow-Modell, mit dem sich die Logik elegant ausdrücken lässt. Zudem werden von Beam auch verschiedenste Runner unterstützt, u.a. Apache Flink, Apache Spark und Apache Samza, s.a. Beam Capability Matrix. Es ist jedoch zu beachten, dass die Runner unterschiedlichste Fähigkeiten haben und die Bereitstellung einer übergreifenden API ein schwieriges Unterfangen bleibt.
Beam hat darüberhinaus ein umfangreiches Set an eingebauten I/O-Transformationen, die einen großen Teil der Daten-Pipeline-Anforderungen abdecken dürfte. Und falls diese nicht ausreichen sollten, können auch benutzerdefinierte Transformationen definiert werden.
Zum Weiterlesen
- Eric Evans: Domain-Driven Design
ein nicht einfach zu lesendes Buch, aber die kanonische Quelle für Domain-Driven Design.
In Kapitel IV wird das Ermitteln der Domänengrenzen beschrieben.
- Vaughn Vernons: Implementing Domain-Driven Design
- konzentriert sich auf strategisches Design und erläutert in Kapitel 2 ausführlich, wie eine Domäne in begrenzte Kontexte untergliedert wird.
- William Kent: Data and Reality
- und auch wenn das Buch etwas in die Jahre gekommen ist, so ist es doch weiterhin relevant für das Datenmanagement.