Das Szenario

Sie kennen das. Während der Entwicklungsphase einer datenintensiven Anwendung ist die Performance ihrer Abfragen im absolut grünen Bereich. Die Tabellen in der Datenbank sind noch nicht sehr voll und die Indizes, wie auch Datenbankdateien sind nicht fragmentiert. Ihr Datenbankserver ist nicht stark ausgelastet und alles scheint perfekt zu sein. Der Kunde nimmt ihre Software ab.

Dann aber wächst die Anzahl der Nutzer, die Daten werden immer zahlreicher und die Abfragepläne der Datenbank stören sich am defragmentierten Index oder zu großen Datenmengen. Die Anwendung wird langsamer, bis die Zufriedenheit ihrer Nutzer abnimmt und diese den Umstand melden.

Jetzt, zu einem Zeitpunkt, an dem die Unzufriedenheit schon um sich greift, ist die Lösung der IT-Abteilung dann meistens eine Hardwarelösung. Mehr Prozessoren, mehr Arbeitsspeicher, schnellere Festplattensysteme. Eventuell müssen Datenbanken migriert werden. Es wird um Ressourcen gekämpft, organisatorisch wie technisch. Und all das während die Unzufriedenheit beim Kunden wächst. Natürlich verschlingt der ganze Aufruhr auch noch eine Menge Budget. Eventuell ist es auch nicht so einfach und erfordert eine Migration inkl. Technologiewechsel, auf beispielsweise IN-Memory oder MPP Systeme, die unter bestimmten Umständen schlechter sind als die bisherige Lösung.

Nutzt man Clouddatenbanken, schiebt man den Regler für die Datenbankperformance einfach höher. Das skaliert in gewissem Maße horizontal – allerdings auch im Preis!

Doch wie sieht eine schlaue Lösung aus?

Als IoT Softwareunternehmen fokussiert SANDY sich als erstes auf das Anliegen des Kunden bzw. Endkunden. Diese Philosophie wird bei der Entwicklung von UseCases konsequent berücksichtigt und steht an oberster Stelle. Danach wird die Entwicklung der Anwendung ausgerichtet.

Eine Methode, um die Performance einer Anwendung nachhaltig aufrecht zu erhalten, ist das sogenannte Sharding. Dabei werden die Daten, vereinfacht gesagt, so abgelegt, dass in späteren SQL- Anweisungen möglichst keine Filter auf die Daten angelegt werden müssen.

Um die Methode zu veranschaulichen, wählen wir ein fiktives Beispiel für die Echtzeitabrechnung von Mobilfunknummern. Das ging schon vor 20 Jahren und zwar ohne die ganzen MPP und IN-Memory Technologien. Die Älteren unter Ihnen werden sich noch erinnern, Sekunden nach dem Ende eines Telefonats kam eine SMS mit der Information über das verbleibende Guthaben.

Herkömmliche Methode am Beispiel von Prepaid Handy Verbindungen

In einer Tabelle mit n-Mobilfunknummern ist das Filterelement zum Abrechnen  z.B. die Mobilfunknummer. Die Tabelle kann in Realität noch mehr Informationen, wie Geokoordination o.ä. enthalten. Ein Anruf oder SMS führt zu einer weiteren Zeile, sodass alle Aktionen von allen Kunden in einer großen Tabelle landen.

Ein Paradies für Analysen

In einer einzigen Tabelle kann man zum Beispiel sehr leicht herausfinden, ob bestimmte Tarife zu mehr Auslandsgesprächen führen oder, ob diese abnehmen und man vielleicht die Gebühren senken sollte. Doch für unsere Echtzeitanalysen ist das nicht optimal.

Jede Anfrage einer Echtzeitanwendung muss zwangsweise die Tabelle filtern.

Hier ein Beispiel einer SELECT-Anweisung, um alle Aktionen einer Mobilfunknummer zu finden:

SELECT * FROM TabellePrePaid WHERE Mobilfunknr = “49151000000002“

Durch alle Gespräche aller Kunden wird diese Tabelle im Laufe der Zeit immer größer, fragmentiert und die Ausführungspläne werden nicht mehr optimiert. Die Fähigkeit, einem Kunden Sekunden nach dem Anruf mitzuteilen zu können, wie hoch sein aktuelles Guthaben noch ist, wird langsamer. Irgendwann passieren diese Auswertungen nicht mehr in Echtzeit, sondern allenfalls Near-Time oder gar nicht mehr. Die eingangs beschriebenen Lösungsszenarien werden von der IT-Abteilung durchgearbeitet. Das führt dazu, dass die Kosten steigen oder explodieren.

Sharding als Alternative

Statt mit einem unnötig teuren IT-Wettrüsten kann man das Thema Big Data auch mit cleverer Methodik lösen. In unserem Beispiel könnte man aus Kundensicht doch auch eine Tabelle je Kunde erstellen. Wird eine SIM-Karte aktiviert, so wird eine neue Tabelle angelegt. Wird die SIM-Karte deaktiviert, kann man die Tabelle umbenennen und in ein Archiv verschieben, um gesetzliche Aufbewahrungsfristen zu erfüllen. Das spart Lösch-Jobs in einer großen Tabelle und weder Tabelle, noch Index würden fragmentiert werden.

So sieht die Tabelle PrePaid_49151000000002 für die Mobilfunknummer = “49151000000002“ aus.

Es fällt auf, dass diese entgegen der oben genannten Tabelle nur noch zwei Zeilen hat und die Spalte Mobilfunknummer, die vorher in der WHERE-Klausel gefiltert wurde, nicht mehr existiert. Das spart sogar Speicherplatz.Eine Abfrage aus unserer Anwendung, um in Echtzeit alle Gespräche der Mobilfunknummer mit dem entsprechen Tarif zu bewerten, sieht dann so aus:

SELECT * FROM TabellePrePaid_49151000000002

Das heißt, es wird nicht gefiltert, sondern direkt die richtige Tabelle, unweigerlich der Güte des jeweiligen SQL Optimizers, angesprochen. Wir verlassen uns dabei nicht auf datenbankherstellerspezifische Partitionstechniken, Filegroups oder ähnliches.

100.000 Mobilfunknummern = 100.000 Tabellen – Na und?

Sicherlich es gibt Begrenzungen, wie viele Tabellen in einer Datenbank sein dürfen oder man haben möchte, doch eine Datenbank als logische Einheit kostet nicht viel. Erstellen wir nur 10 Datenbanken, so sind es bloß noch 10.000 Tabellen je Datenbank.

Vor- und Nachteile von Sharding

Vorteile
  • Abfragen bleiben schnell, da die Datenmenge je Tabelle klein bleibt
  • Archivierung kann durch Konfiguration gelöst werden
  • Die Datenbanktechnologie ist nicht mehr entscheidend
  • Kosten für den Datenbankserver bleiben klein, da teure, zusätzliche Hardware durch Methodik ersetzt wird
  • Vorteile durch Know-how der bisherigen Technologie bleibt bestehen (z.B. OLTP)
Nachteile
  • Sharding-schlüsselübergreifende Auswertungen werden komplizierter und langsamer
  • Die Shards müssen individuell beladen werden
  • Sie brauchen Erfahrung bei der Shardingstrategie und Umsetzung

Doch bei allen Nachteilen

Ihre Anwendung bleibt unseren Erfahrungen nach nachhaltig schnell und günstig. In unserem Beispiel wird eine Mobilfunknummer nie so viel telefonieren können, dass eine Datenbanksoftware auch nur ansatzweise ein Problem bekommen kann.

Think about it

In unserem einfachen Beispiel könnte man z.B. eingehende und ausgehende Telefonate trennen, da man für die Abrechnung lediglich die ausgehenden Verbindungen benötigt. Für den Verbindungsnachweis würden beide Tabellen benötigt. Die Tarife könnte man je Mobilfunknummer speichern. Entscheiden Sie für jeden Use-Case individuell, welche Daten wirklich bei einer Kundenanfrage in einer Tabelle vorliegen müssen. So werden große Datenprobleme auf einmal ganz klein. Technologien sind schön und gut, aber es braucht auch Methodik.