Unveränderliche Daten

Motivation

Immutable Data, also unveränderliche Daten, ist ein Prinzip, das besagt, dass Daten, die einmal erzeugt werden, nachträglich nicht mehr verändert werden können.

Daten nicht mehr zu verändern klingt zunächst unintuitiv, bietet aber eine Reihe von Vorteilen. Bei veränderlichen Daten ist das Synchronisieren und Thread-sicher halten von geteilten Daten sehr aufwändig, fehleranfällig und kostet Performance, da jeder, der auf die Daten zugreift, sie auch ändern kann. Sind die Daten unveränderlich, entfällt dieses Problem. Jede Kopie ist immer aktuell, eine Referenz zeigt immer auf das richtige Objekt. Daten können ausgetauscht und geteilt werden, ohne dass Programmabstürze oder falsche Datenbestände zu befürchten sind.

Nun mag man einwenden, dass Daten sich doch aber ändern. Wenn jemand umzieht, dann ändert sich seine Anschrift, und diese muss schließlich auch in einem Datensystem aktualisiert werden, alles andere wäre fernab der Realität. Dies wird mit unveränderlichen Daten so gelöst, dass jede logische Änderung als neues Faktum erzeugt und an das vorherige Faktum angehängt wird, statt es zu ändern. Dieses Konzept wird als append-only bezeichnet.

Nur die Fakten

Produktive Kommunikation konzentriert sich auf den Austausch von Fakten statt Interpretationen. Genauso verhält es sich in Datensystemen. Es sollten immer zuerst beobachtete Fakten eingespielt werden. Fakten beschreiben Sachverhalte, die als wahr oder ursprünglich (daher auch Rohdaten) angenommen werden, wie z.B. ausgelesene Messwerte, Eigenschaften von Dingen, vom Nutzer eingegebene Formulare, aufgetretene Ereignisse, usw.

Aus den Fakten lassen sich Informationen ableiten. Dies geschieht letztlich um einen Nutzer oder Betrachter zu informieren - über den Zustand des Systems, des Unternehmens, eingetretene Ereignisse, usw. Die abgeleiteten Informationen werden auf Anfrage berechnet oder vorberechnet im Datensystem vorgehalten, um den Zugriff zu beschleunigen und zu erleichtern. Neben der technischen Fehlertoleranz von verteilten Systemen ergibt sich hier auch eine Fehlertoleranz auf der menschlichen Ebene (englisch human fault-tolerance). Enthält ein Algorithmus, der abgeleitete Daten berechnet, einen Programmierfehler, kann dieser nachträglich korrigiert werden. Die bisherigen abgeleiteten Daten können gelöscht und aus den Fakten neu ermittelt werden.

Als Beispiel zählt jede aufgegebene Bestellung in einem Online-Shop als Faktum. Selbst wenn in einem Datenfeld ein Eingabefehler vorliegt, handelt es sich erstmal um die ursprünglichen Fakten, wie sie beobachtet wurden. Die Summe der Bestellwerte pro Tag wiederum ist eine Information, die grob aus der Aggregation der Preise der einzelnen Produkte aus den Bestellungen an dem Tag abzüglich gewährter Rabatte abgeleitet wird.

Nathan Marz definiert daher Information = Funktion(Fakten).1

Auch der Bestellwert einer einzelnen Bestellung ist eine Information und muss daher nicht in der Bestellung gespeichert werden. Dies geschieht üblicherweise erst in einem zweiten Schritt zur Anreicherung der Fakten, um die Weiterverarbeitung zu optimieren und zu vereinfachen.

Time and time again

Schaut man sich die Realität genauer an, stellt man fest, dass ein wichtiger Faktor bei Update-Überlegungen leicht vergessen wird - die Dimension Zeit. Die Wirklichkeit wird als eine Reihe von Augenblicken erlebt und steht niemals still, ist einem ständigen Wandel unterzogen. In Systemen Daten ohne Zeitbezug zu speichern, indem man einen Wert vorhält und diesen bei Änderungen überschreibt, ignoriert diese Tatsache und entspringt womöglich der Tendenz, etwas, das ständig im Fluss ist, ein festes gedankliches Fundament zu geben.

Was bedeutet das für unsere Daten? Fakten sind für einen Zeitpunkt oder einen Zeitraum wahr und werden es auch immer bleiben. Sie sind zeitlich unveränderbar und werden nur von neueren Fakten gefolgt, die dann wiederum für ihren Zeitraum gelten. Und so geht es immer weiter, solange wie das System (oder das Unternehmen oder das Universum) existiert. Das ist das bereits erwähnte append-only.

Wenn jemand umzieht, dann ändert das nichts daran, dass er zwei Jahre in der vorherigen Wohnung gewohnt hat, und es bedeutet auch nicht, dass die neue Adresse für immer gilt. Es ist nur die neueste oder aktuelle Anschrift, und auch das hängt immer nur vom zeitlichen Standpunkt des Betrachters ab.

Ein Faktum mit Zeitbezug lässt sich gut als Ereignis modellieren (siehe auch mein Blogpost über Streaming).

Everything that happened

Wenn wir die Dimension Zeit in die Fakten aufnehmen, z.B. indem man sie mit einem Zeitstempel versieht, und Daten als Ereignisse nicht aktualisiert sondern anhängt, bekommen wir eine Historie aller Änderungen, die wir später auswerten können.

Es macht beispielsweise einen Unterschied, ob ich den endgültigen Warenkorb eines Kunden analysiere, oder ob ich auswerten kann, welche Produkte er während des Stöberns in den Warenkorb gelegt und wieder herausgenommen oder durch andere ersetzt hat.

Warenkorb mit Events

Auch beim Beispiel mit der geänderten Adresse kann es von Belang sein zu wissen mit welcher PLZ Bewegungsdaten assoziiert sind. Theoretisch könnte man die PLZ auch in die Bewegungsdaten mit aufnehmen um sie später direkt dort auszuwerten, hat dort aber natürlich nichts verloren. Jede beliebige Eigenschaft in alle Bewegungsdaten aufzunehmen würde das Modell aufblähen, und zu guter Letzt kennt man beim Erfassen der Daten schlicht noch nicht alle Analysen, die später gefahren werden sollen.

Den Zeitbezug in den Daten herstellen

Datensysteme fügen den Daten oft einen Zeitstempel hinzu. Dabei handelt es sich um den Erfassungszeitpunkt. Zwischen dem Auftreten eines Ereignisses und dem Erfassen im System kann beträchtlich viel Zeit vergehen, beispielsweise wenn ein Ereignis im Online-Shop per JavaScript erfasst wird, die Übertragung aber fehlschlägt und erst beim nächsten Besuch des Kunden gelingt. Auch kleinere Abweichungen oder das Übertragen von Ereignissen von mehreren Systemen parallel können schon dazu führen, dass die Fakten nicht in der richtigen Reihenfolge im Datensystem ankommen.

Im Streaming wird dies out of order and late-arriving events genannt. Das Kapitel Streaming in Fast Data in der Praxis beschreibt, wie man mit solchen Events umgeht.

Um eine richtige Reihenfolge überhaupt herstellen zu können braucht man also den Zeitpunkt des Auftretens, der so früh wie möglich erhoben werden sollte, im obigen Beispiel schon auf der Website in JavaScript vorm Übertragen ans Backend. Das ist natürlich nur möglich, wenn die Ereignisse im eigenen System auftreten. Wenn ein externes Ereignis ins System eingespielt wird, wie im Beispiel des Wetterdienstes, muss der richtige Zeitstempel aus den eingehenden Daten extrahiert werden.

Da es schwer ist, die Uhren in verteilten Systemen synchron zu halten, kann auch ein Zeitstempel letztlich keine Garantie für die richtige Reihenfolge der Daten geben. Gibt es eine logische Reihenfolge, die durch den Prozess vorgegeben ist, sollte diese bevorzugt werden.

Datenhaltung

Speichert man alle Fakten, also sämtliche Änderungen, dauerhaft, können große Datenmengen entstehen. Zudem möchte man nicht immer alle Fakten durchlaufen um einen endgültigen oder aktuellen Wert zu ermitteln. Dazu wird ein Snapshot, also ein Schnappschuss eines bestimmten Zustandes, angelegt, der in einer Datenbank zur Abfrage bereit hinterlegt wird.

Beim Adressbeispiel würde man die letzte Adressänderung pro Benutzer vorhalten; im Onlineshop wäre es der aktuelle Warenkorb. Ein anderes leicht nachzuvollziehendes Beispiel sind Seitenbesuche. Der Aufruf der eigenen Website durch einen Benutzer wird als Faktum hinterlegt. Da in einer Auswertungsstatistik nicht jedes mal alle Seitenbesuche aufgerufen und zusammengezählt werden sollen, werden als abgeleitete Daten die Seitenbesuche pro Tag berechnet. Als Snapshot wird dann der finale Wert pro Tag hinterlegt und kann auf einer Übersichtsseite schnell angezeigt werden.

Zur Datenhaltung von Snapshots besonders geeignet sind Key-Value-Stores. Auch der Message Broker Apache Kafka bietet Compacted Topics, die nur den neuesten Wert für einen Key vorhalten. Mehr dazu in meinem Blogpost über Kafka.

Historische Fakten überführt man dann in einen Long Term Storage wie HDFS oder S3.

Auch das Prinzip der Datensparsamkeit sollte beim Langzeitspeichern von Fakten beachtet werden. Zudem müssen die Daten laut DSGVO den Nutzern ausgehändigt oder gelöscht werden können.

Fazit

Fakten unveränderlich mit Zeitbezug ins System append-only aufzunehmen bildet die Daten realitätsnaher ab als wenn man vorhandene Daten aktualisiert. Das vereinfacht letztlich den Umgang mit den Daten, und ermöglicht neue Anwendungsfälle und Analysen.

  1. Wie ausgeführt in seinem Buch Big Data

Diesen Post teilen

RSS-Feed

Neue Posts direkt im Newsreader.

RSS-Feed abonnieren

Newsletter

Neue Posts sowie Neuigkeiten rund um Big Data, Spark, und Scala. Maximal eine E-Mail im Monat.