Jetzt war mal wieder so ein Vortrag bei einer der vielen User-Groups, in der ich drin bin. Diesmal ging es um Riak und der Vortrag war von einem der Entwickler und war wirklich gut. Ein Stück weit wurde die Grundsatzthematik der NoSQL-Datenbanken behandelt, wobei natürlich Riak im Zentrum stand.
Während es bei den SQL-Datenbanken vielleicht etwa vier gibt, die einigermaßen austauschbar sind, was die Funktionalität betrifft (Oracle, MS-SQL-Server, DB2 und PostgreSQL, mit Einschränkungen auch mySQL und MariaDB), ist hier die Frage relevant, das richtige Werkzeug für die richtige Aufgabe zu verwenden. Und das richtige Werkzeug sind oft die relationalen transaktionalen Datenbanken. Die Austauschbarkeit der relationalen Datenbankprodukte gilt natürlich nur, wenn man eine neue Applikation entwickelt, nicht wenn man Software nachträglich umschreiben muss und die Datenbankadministrationsprozesse nachträglich ändern muss.
Nun sind die Daten ja immer sehr wichtig, sonst könnte man sich den Aufwand ja sparen, sie zu speichern. Und wenn die Datenbank nicht transaktional ist, dann ist das gruselig, weil die Daten nicht zuverlässig und nicht genau genug gespeichert werden. Das Versprechen der transaktionalen Datenbanken für Transaktionen wird ja kurz mit „ACID“ bezeichnet:
- „Atomic“ bedeutet, dass die Transaktion entweder komplett oder gar nicht ausgeführt wird
- „Consistent“ bedeutet, dass die Daten immer in einem konsistenten Zustand sind.
- „Isolated“ bedeutet, dass verschiedene gleichzeitig laufende Transaktionen sich nicht gegenseitig beeinflussen.
- „Durability“ bedeutet, dass die Daten nach Abschluss der Transaktion garantiert dauerhaft gespeichert sind.
Super, da kann nichts mehr schief gehen. Und Software von Oracle oder IBM ist serienmäßig komplett fehlerfrei, von Microsoft sowieso und bei PostgreSQL bauen die Entwickler der Software, die die Datenbank verwendet, allfällige Fehler der DB-Software selbst noch kurz in der Nacht aus… Aber fairerweise muss man sagen, dass die Kernfunktionalität der Datenbankprodukte tatsächlich recht zuverlässig funktioniert und die nervigen Fehler eher am Rande bei unwichtigen Dingen wie Installern oder Security-Features aufgetreten sind, die hier nicht das Thema sind. 😉
Also gut, man kann also mal annehmen, dass die DB-Software vernünftige Zuverlässigkeit hat. Was ist mit der Hardware? In einem großen Rechenzentrum muss rein rechnerisch immer irgendwo ein Hardwaredefekt sein. Ist aber kein Problem, man baut die Hardware und damit die Datenbankinstallation einfach redundant auf. Und es gibt tolle Mechanismen, die mit erheblichem Aufwand sicherstellen, dass ACID immer noch gilt. Man hat also eine Datenbank, die auf mehreren Rechnern läuft und sich gegen außen wie einer verhält. Eine Transaktion kann auch mehrere dieser Rechner involvieren. Egal was passiert, soll immer ACID-Transaktionalität gelten. Mit „Two-Phase-Commit“ und solchen Werkzeugen kann man das hinbekommen. Zumindest sagt man, dass es in der Praxis zuverlässig funktioniert. Vielleicht bis zu einer gewissen Größe, denn wenn eine einzige Datenbank ein ganzes großes Rechenzentrum beansprucht, kann man sich sicher auf einen hohen Stromverbrauch verlassen, aber mehr will ich dazu hier nicht sagen. Reale Rechenzentren, die transaktionale Datenbanken betreiben, haben erfahrungsgemäß auch viele mehr oder weniger unabhängige Datenbanken am Laufen.
Man kann also mit recht großen ACID-transaktionalen Datenbanken die Unzuverlässigkeit der Hardware recht gut in den Griff bekommen. Das ist nicht billig und es lohnt sich gute Datenbankberater heranzuziehen.
Wie sieht es mit der Applikationssoftware aus? Die wird heutzutage ja oft in Java geschrieben und läuft deshalb in der Sandbox, was ja alle Probleme verhindert, weil die Sandbox unterbindet, dass irgendwas gefährliches gemacht wird… 😉
Ist die Applikationssoftware fehlerfrei? Oder zumindest so fehlerfrei, dass nie mit den Daten etwas schief gehen kann? Vielleicht, wenn man optimistisch ist? Wenn wir schon bis hierher Optimismus aufbauen konnten… Die transaktionale Datenbank ist ein nütziches Werkzeug, wenn man sie mit hinreichend korrekter Software benutzt. Aber das machen wir alle und auf dem Laptop des Entwicklers hat es wirklich funktioniert, es sind halt die Benutzer schuld, die mehrere Requests gleichzeitig abschicken. Was ist mit dem „I“ aus ACID passiert? Ja, die Datenbank macht es schon richtig, aber die Applikation stürzt ab oder erzeugt korrumpierte Daten. Oder verwendet zu kleine oder zu große Transaktionen. Schade…
Nun kommt aber noch die Software- und Systemarchitektur ins Spiel. Man fängt an, ein großes System über mehrere Server zu verteilen, Caching wird verwendet, Teilbereiche der Daten werden über Services angesprochen. Natürlich arbeitet man mit tollen Frameworks und die Datenbank ist für den Applikationsentwickler schon recht weit weg, aber immer noch macht man irgendwo implizit oder explizit schöne Transaktionen auf und beendet sie mit commit oder rollback. Niemand weiß mehr, in welcher Schachtelungstiefe von solchen Methoden, die implizit Transaktionen durchführen, man sich befindet und mit bestimmten Mustern kann man das aus Versehen austricksen, aber so etwas passiert natürlich nicht. Wie sieht es jetzt mit ACID aus?
Kurz gesagt, für reale Applikationen muss man genauer hinschauen, ob ein etwas schwächeres Modell als ACID wirklich ein Nachteil ist.
Nun muss man aber noch einmal auf den Ausgangspunkt zurückkommen. Transaktionen lassen sich sehr gut für nicht-relationale Datenbanken definieren und auch implementieren. Umgekehrt kann man für manche Zwecke durchaus relationale SQL-Datenbanken verwenden, die nicht transaktional sind. Oder man hat wie bei MongoDB Transaktionen für einzelne DB-Operationen, kann diese aber nicht zusammenfassen.