Datenbanksysteme Teil 2

- Falk Borgmann

Das Grundlegende

Bei einem zentralen System sind dessen Komponenten nicht verteilt. Verteilung definieren wir hier nicht als „Sicherheitskopie“ oder „Cold Standby“ bzw. Schattendatenbank, sondern als echten verteilten Service, der stets in getrennten Entitäten voneinander existiert. Kopien von Daten, um etwa einen Totalverlust von Informationen im Falle eines Feuers im Rechenzentrum zu vermeiden, können auch bei einem zentralen System existieren. Ein typisches Beispiel aus der Praxis sind die Oracle-Datenbanken unter einer klassischen SAP-R3-Lösung.

Die wichtigste Eigenschaft solcher Systeme ist die sogenannte ACID-Transaktionalität (Atomicity, Consistency, Isolation, Durability – Atomarität, Konsistenz, Isolation, Dauerhaftigkeit). Ohne im Einzelnen auf die vier Bestandteile einzugehen, geht es im Kern darum, dass sich eine Datenbank gegenüber einer Anwendung immer konsistent verhält. Das bedeutet, auf eine Frage bekommt man zu einem bestimmten Zeitpunkt immer die gleiche Antwort. Diese Antwort kann auch ein Fehler oder falsch sein, jedoch wird sie immer gleich lauten.

Bei verteilten Systemen ist diese Eigenschaft in der Regel nicht gegeben. Der verteilte Gegenentwurf zur ACID-Transaktionalität bewegt sich im Spannungsfeld eines anderen Grundsatzes, dem sogenannten CAP-Theorem. Es besagt, dass in einem verteilten System lediglich zwei von drei Aspekten gleichzeitig sichergestellt werden können: Konsistenz (C = Consistency), Verfügbarkeit (A = Availability) und Ausfalltoleranz (P = Partition Tolerance).

Die im CAP-Theorem enthaltene Konsistenz ist übrigens aus Sicht einer Anwendung, die eine Anfrage an die Datenbank richtet, am ehesten mit den ACID-Eigenschaften eines zentralen Systems zu vergleichen. Jeder, der jetzt um die Ecke kommt und erklärt, dass die Konsistenz des CAP-Theorems nur in verteilten Systemen gilt und keine einzeln gekapselte Transaktion widerspiegelt, dem sei versichert: Ja. Aber aus Applikationssicht und, um die generellen Herausforderungen zu verstehen, ist dieser Vergleich dennoch zulässig.

Wer jetzt also denkt, dass man Konsistenz (wie bei ACID) in einem verteilten System herbeiführen kann, indem man auf Verfügbarkeit oder Ausfalltoleranz einer Lösung verzichtet, liegt richtig. Nur mit welchen Preis bezahlt man in einem verteilten System für eine vollständige Konsistenz? Die einfache Antwort ist: mit Performance. Wir nähern uns unweigerlich der fachlichen Anforderung, also der Frage, welche Eigenschaft in einem konkreten Anwendungsfall wichtig ist.

Warum sollte man Daten überhaupt verteilt verwalten?

Zum Beispiel dann, wenn Daten auch verteilt, über viele Standorte produziert oder abgerufen werden. Das können Niederlassungen eines Unternehmens oder auch global gehostete Webseiten sein. Denkt man einmal an die Menge der weltweiten Suchanfragen an Google oder Facebook. Im Jahr 2018 hatte Google etwa 3,5 Milliarden Suchanfragen pro Tag. Stellen wir uns vor, Google würde versuchen, diesen globalen Service mit nur einem einzigen zentralen System zur Verfügung zu stellen: 3,5 Milliarden Suchen mit circa 1.000 Treffern pro Suche, die an einen Client ausgeliefert werden. Das sind 3,5 Billionen Datensätze am Tag. Und da sprechen wir noch nicht einmal von den zu durchsuchenden Inhalten, auf denen die Treffer basieren. So ein Datenvolumen kann nicht einfach in einem einzigen zentralen Storage gehalten und dann über das Internet weltweit verteilt werden. Allein die Latenz zwischen den Anfragen eines Clients in Europa oder Asien und der Antwort einer Search Engine in den USA wären viel zu groß. Ergo ist es in so einem Fall sinnvoll, die Daten zumindest geografisch dort abzulegen, wo sie auch benötigt werden. Das Google-Beispiel ist sicherlich extrem, aber es eignet sich gut, um die generelle Problematik zu verdeutlichen. Und diese Probleme machen sich eben schon bei deutlich kleineren Infrastrukturen oder Datenvolumen bemerkbar und sind durchaus bei anders gelagerten Anwendungsfällen relevant.

Erkauft wird der Service also dadurch, dass ein verteiltes System nicht hundertprozentig konsistent sein kann, wenn man auf die Vorzüge der Verteilung nicht verzichten will. Wird beispielsweise ein neuer Datensatz in das System geschrieben, muss dieser zunächst im gesamten System verteilt werden. Je nach Lösungsdesign, Verteilungsalgorithmus und der Anzahl beteiligter Hardware-Instanzen kann das auch mal länger dauern. In dieser Phase ist es möglich, dass zwei unterschiedliche Clients auf die gleiche Frage zwei voneinander abweichende Antworten erhalten. Und das, obwohl man dasselbe System fragt.

Dafür kann so ein System eine vollständige Ausfallsicherheit für einzelne Instanzen bieten, da es bei einem Cluster von zum Beispiel 100 Servern keinen Unterschied macht, ob einer davon offline ist oder nicht. Sofern die 99 verbleibenden Server in der Lage sind, Clientanfragen gleichberechtigt zu beantworten, wäre dazu noch eine vollständige Verfügbarkeit des Systems gegeben. Also ein Verzicht auf Konsistenz (C = Consistency) zugunsten von Verfügbarkeit (A = Availability) und Ausfalltoleranz (P = Partition Tolerance).

In diesem Zusammenhang könnte einem auch der Begriff „BASE“ begegnen, wobei das „E“ hier für „eventual consistency“ steht. Es handelt sich dabei um eine Wortschöpfung, die häufig im Umfeld verteilter Systeme Verwendung findet. Damit ist gemeint, dass eine echte Datenkonsistenz in einem verteilten System erst nach einem bestimmten Zeitraum erreicht wird. Eine öffentliche Blockchain ist ein schönes Beispiel für „eventual consistency“ in einem verteilten System.

Welche Eigenschaften sind bei einem Anwendungsfall wichtig? Wird eine hohe Verfügbarkeit benötigt, bei der viel Datenvolumen prozessiert wird? Dabei wäre aber tolerabel, dass vielleicht mal ein Datensatz verloren geht oder etwas verzögert abrufbar ist? Dann können verteilte Konzepte eine Lösung sein. Oder ist absolute Sicherheit notwendig, dass kein einziger Datensatz verloren geht und Informationen immer konsistent sind (die Steuerbehörde lässt grüßen)? Dann vielleicht doch eher ein zentrales Datenbanksystem?

In der folgenden Tabelle sind auf einer sehr groben Ebene die Eigenschaften der Konzepte zusammengefasst:

Wenn wir heute von zentralen Datenbanksystemen sprechen, reden wir immer von relationalen Datenbanksystemen. Deren grundlegendes Datenmodell ist einfach zu verstehen: Jeder, der schon mal eine Excel-Tabelle erstellt hat, weiß im Grunde, wie eine relationale Tabelle funktioniert und wie man daraus Informationen extrahieren kann, auch ohne selbst ein ER-Modell (Entity-Relationship-Modell) designt zu haben.

Egal, ob man ein System von Oracle, Microsoft (MS SQL) oder IBM (DB2) verwendet – sie funktionieren alle nach dem gleichen Prinzip. Und sie gewährleisten alle eine ACID-Zusicherung hinsichtlich der Konsistenz eines Prozesses. Ein wichtiges Paradigma, das schon bei der Entwicklung solcher relationalen Lösungen im Mittelpunkt steht, ist logischerweise der Ausschluss von Inkonsistenzen. Deshalb wird alles getan, um Fehler bei der Verarbeitung von Prozessen zu vermeiden, um nach außen immer konsistent zu bleiben. In diesem Punkt unterscheiden sich echte sogenannte Peer-to-Peer-Datenbanken (verteilte Datenbanken) kolossal, denn sie gehen davon aus, dass Fehler im Regelbetrieb immer wieder passieren können und werden. Schwerpunkt der Entwicklung ist also, bei diesen Systemen mit Fehlern umzugehen und nicht Fehler mit allen Mitteln zu vermeiden. Dieser Grundsatz muss konsequenterweise dazu führen, dass sich Konsistenz zugunsten von Verfügbarkeit und Ausfalltoleranz hintanstellen muss.

Im folgenden Beitrag der Serie „Teil 3 – Relational vs. NoSQL“ betrachten wir insbesondere die sogenannten NoSQL-Datenbanken etwas detaillierter. Hier gibt es unterschiedliche technische Ansätze, die, entsprechend den Anwendungsfällen, differenziert werden müssen.

Share