18. Jänner 2024 von Yannik Rust
AWS DynamoDB: Ein Überblick über die NoSQL-Datenbank in der Cloud
AWS DynamoDB ist ein hochleistungsfähiger NoSQL-Datenbankdienst, der als Key-Value-Storage konzipiert ist. Als vollständig verwalteter, serverloser Dienst bietet DynamoDB eine schnelle, flexible und kostengünstige Lösung für die Speicherung und Abfrage von Daten in der Cloud. In diesem Blog-Beitrag werfe ich einen detaillierten Blick auf die Hauptmerkmale, Design-Patterns und Best Practices von DynamoDB.
Was ist NoSQL?
NoSQL steht für "Not Only SQL" oder "Nicht-SQL" und bezieht sich auf eine große Klasse von Datenbankmanagementsystemen, die sich von klassischen relationalen Datenbanken unterscheiden. NoSQL-Datenbanken wurden entwickelt, um den Anforderungen moderner Anwendungen gerecht zu werden, die große Mengen unstrukturierter oder semi-strukturierter Daten verarbeiten müssen, wie sie in Webanwendungen, Social Media, Big Data und anderen Szenarien vorkommen.
DynamoDB – eine kurze Einführung
DynamoDB ist ein nicht-relationaler Key-Value-Speicher, der auf NoSQL-Prinzipien basiert. Als vollständig verwalteter Dienst in der AWS-Cloud benötigt diese Datenbank keine manuelle Serververwaltung, sodass sich Entwicklerinnen und Entwickler ganz auf die Anwendungsentwicklung statt auf die zugrundeliegende Infrastruktur konzentrieren können.
DynamoDB bietet die Möglichkeit, global verteilte Datenbanken zu erstellen. Diese Architektur ermöglicht es, Daten über verschiedene AWS-Regionen hinweg zu verwalten, wodurch eine hohe Ausfallsicherheit und Verfügbarkeit gewährleistet wird. Die Performance von Abfragen wird dadurch auf Millisekunden reduziert. Durch den Einsatz der Caching-Erweiterung DAX kann sogar eine Latenz im Mikrosekundenbereich erreicht werden. Darüber hinaus ermöglicht DynamoDB Backups und das Zurücksetzen von Daten auf einen bestimmten Zeitpunkt (Point-in-Time Recovery - PITTR). Dies ist wichtig, um Daten vor unbeabsichtigtem Verlust zu schützen. DynamoDB bietet APIs für die Durchführung von CRUD-Operationen (Create, Read, Update, Delete). Transaktionen können auch über mehrere Tabellen hinweg unter Einhaltung der ACID-Prinzipien (Atomicity, Consistency, Isolation, Durability), jedoch ohne Verwendung von Joins, durchgeführt werden.
Aufbau einer DynamoDB
Die Struktur von AWS DynamoDB ist durch eine klare Hierarchie gekennzeichnet, in der Tabellen als oberste Entitäten fungieren. Im Gegensatz zu relationalen Datenbanken gibt es keine strikten Beziehungen zwischen den Tabellen. Jede Tabelle stellt eine eigenständige und unabhängige Entität dar, was eine flexible Datenmodellierung ermöglicht.
Die Leistungskontrolle erfolgt auf Tabellenebene, was bedeutet, dass Entwicklerinnen und Entwickler die Möglichkeit haben, die Performance jeder Tabelle individuell zu optimieren, ohne dass dies Auswirkungen auf andere Tabellen in der Datenbank hat. Die Daten oder Items werden in einem speziellen JSON-Format von DynamoDB gespeichert, was nicht nur eine effiziente Speicherung, sondern auch eine schnelle Abfrage ermöglicht.
Ein Schlüsselelement der Struktur ist der Primärschlüssel, der obligatorisch ist, während der Rest des Schemas flexibel bleibt. Der Primärschlüssel kann einfach (nur ein Attribut) oder zusammengesetzt (zwei Attribute: Partitionsschlüssel und Sortierschlüssel) sein. Diese Flexibilität gilt auch für die anderen optionalen Attribute in der Tabelle.
Die folgende Abbildung zeigt die Struktur einer Tabelle am Beispiel von Computerspieldaten. Hier besteht der Primärschlüssel aus einem Partitionsschlüssel (Player ID) und einem Sortierschlüssel (Game ID). Die einzelnen Attribute sind nicht für jeden Eintrag vorhanden und somit sehr flexibel.
Die hier tabellarisch dargestellten Daten werden im Hintergrund im JSON-Format von DynamoDB gespeichert, weshalb diese Datenbank auch als Dokumentendatenbank bezeichnet werden kann. Für die erste Zeile des obigen Beispiels sieht die JSON-Datei wie folgt aus:
{
"Spieler ID" :{"S":"Spieler 1"},
"Spiel ID" :{"S":"Spiel 1"},
"Datum" :{"S":"2020-01-02"},
"Zeit" :{"N":"62"},
"Punktzahl" :{"N":"34000"},
"Rang" :{"N":"20"},
"Award" :{"S":"Champ"}
}
Die Präfixe S und N stehen für die Datentypen String (S) beziehungsweise Number (N), die im Attribut gespeichert werden. Als einfache Datentypen können auch Boolean (B) und Null (N) verwendet werden. Als weitere Datentypen stehen Listen (L) und Maps (M) sowie der Typ String Set (SS) zur Verfügung.
Indizes in DynamoDB
In DynamoDB ermöglicht die Verwendung von Indizes eine effizientere Datenabfrage. Es gibt zwei Arten von Indizes: den Local Secondary Index (LSI) und den Global Secondary Index (GSI).
Local Secondary Index (LSI)
Ein LSI basiert auf demselben Partitionsschlüssel wie der Primärschlüssel der Tabelle, hat aber einen anderen Sortierschlüssel. Wichtig ist, dass es sich um einen zusammengesetzten Schlüssel handelt. Die Erstellung eines LSI ist auf maximal fünf Indizes pro Tabelle beschränkt und die Größe der indizierten Elemente darf zehn Gigabyte nicht überschreiten. Außerdem müssen LSIs bei der Erstellung der Tabelle definiert werden und können nicht nachträglich hinzugefügt werden.
Global Secondary Index (GSI)
Ein GSI ermöglicht es, den gleichen oder einen anderen Partitionsschlüssel als den Primärschlüssel der Tabelle zu verwenden. Der GSI kann entweder ein einfacher oder ein zusammengesetzter Schlüssel sein. Jede Tabelle kann bis zu 20 GSIs haben, und es gibt keine Größenbeschränkungen für die indexierten Elemente. GSIs können jederzeit erstellt und gelöscht werden und ermöglichen Abfragen über Partitionen hinweg. Es ist wichtig zu beachten, dass GSIs nur eine potentielle Konsistenz bieten (siehe unten).
Datenkonsistenz
Die Konsistenzmodelle von AWS DynamoDB spielen eine entscheidende Rolle bei der Steuerung von Lese- und Schreibvorgängen. Um die Hochverfügbarkeit von DynamoDB zu gewährleisten, werden die zu speichernden Daten verteilt abgelegt. Grundsätzlich verfolgt AWS dabei das Prinzip der möglichen Konsistenz. Das bedeutet, dass es nach dem Schreiben der Daten keine unmittelbare Garantie dafür gibt, dass alle Kopien der Daten zu einem bestimmten Zeitpunkt identisch sind. Dennoch ist es mit DynamoDB möglich, für Lese- und Schreiboperationen je nach Anwendung ein bestimmtes Maß an Konsistenz zu wählen.
Konsistenz für Leseoperationen
Bei hoher Konsistenz wird immer auf die aktuellen Daten zugegriffen. Dies erfordert jedoch explizite Anfragen beim Lesen. Starke Konsistenz garantiert, dass die zurückgegebenen Daten die aktuellsten und konsistentesten sind.
Im Gegensatz dazu garantiert die schwache Konsistenz nicht, dass die zurückgegebenen Daten die aktuellsten sind. Sie ist die Standardkonsistenzstufe und ist kostengünstiger, etwa 50 Prozent günstiger als starke Konsistenz.
Transaktionale Konsistenz bietet ACID-Unterstützung für eine oder mehrere Tabellen innerhalb eines einzelnen AWS-Kontos und einer Region. Obwohl sie die zuverlässigste Konsistenz bietet, kostet sie doppelt so viel wie starke Lesekonsistenz.
Schreibkonsistenz
Die Standard-Schreibkonsistenz ermöglicht eine einfache Durchführung von Schreiboperationen. Die Daten können kurzzeitig inkonsistent erscheinen, bevor sie intern von DynamoDB harmonisiert werden.
Im Gegensatz dazu bietet die transaktionale Schreibkonsistenz ACID-Unterstützung für Schreiboperationen. Dies ist jedoch doppelt so teuer wie die Standard-Schreibkonsistenz.
Preisstruktur
Das Preismodell von AWS DynamoDB bietet Entwicklerinnen und Entwicklern Flexibilität und Skalierbarkeit, um den Anforderungen ihrer Anwendungen gerecht zu werden. Es gibt zwei Hauptoptionen: "Provisioned Capacity" und "On-Demand Capacity".
Unter dem Modell der "Provisioned Capacity" zahlen Nutzerinnen und Nutzer für die Kapazität, die sie vorab definiert haben. Dieses Modell wird vor allem für produktive Systeme verwendet, bei denen die Auslastung bekannt ist. Die Kapazität umfasst die Anzahl der Lese- und Schreibvorgänge pro Sekunde. Diese Schreiboperationen werden auch als Read/Write Capacity Units (RCU/WCU) bezeichnet. Eine Kapazitätseinheit entspricht einer Anfrage pro Sekunde.
RCU (Read Capacity Unit) werden in Blöcken von vier Kilobyte gemessen, wobei der letzte Block immer aufgerundet wird. 1 RCU entspricht einem stark konsistenten Lesevorgang, zwei eventuell konsistenten Lesevorgängen oder einem halben transaktionalen Lesevorgang pro Sekunde.
WCU (Write Capacity Unit) werden in Blöcken von einem Kilobyte gemessen, wobei der letzte Block immer aufgerundet wird. Eine WCU entspricht einer Standard-Schreiboperation oder einer halben transaktionalen Schreiboperation pro Sekunde.
Zur Veranschaulichung wird daher ein Beispiel für die Berechnung der Anzahl der Capacity Units für das Schreiben und Lesen eines 15 Kilobyte großen Objekts in die und aus der Datenbank mit den verschiedenen Konsistenztypen gegeben.
Wird die bereitgestellte Kapazität durch eine zu hohe Anzahl von Anfragen überschritten, kann es zu einer Begrenzung der Datenbank kommen, so dass keine weiteren Anfragen mehr bearbeitet werden können. Um dieses Problem zu umgehen, kann die Funktion Auto-Scaling verwendet werden. Sie passt die Kapazität automatisch an vordefinierte Grenzen an.
Unter dem Modell der "On-Demand Capacity" zahlen die Nutzerinnen und Nutzer pro Anfrage für Lese- und Schreibvorgänge. Es ist keine vorherige Bereitstellung erforderlich und die Kapazität passt sich dynamisch an die Auslastung an. Diese Option eignet sich besonders für Umgebungen mit unvorhersehbarem Datenverkehr wie Test- und Entwicklungsumgebungen. Für die Abrechnung werden hier Request Units verwendet. Diese entsprechen in der Berechnung den Capacity Units, sind aber teurer.
Zusätzlich zu den Kapazitätskosten fallen Kosten für Storage, Backups, Replikation, Caching und externen Datentransfer an.
Best Practices für DynamoDB
Um die Performance, Skalierbarkeit und Effizienz von AWS DynamoDB optimal zu nutzen, sollten einige Best Practices beachtet werden:
Effizientes Schlüsseldesign
- Der Partitionsschlüssel sollte viele eindeutige Werte haben, um eine gleichmäßige Verteilung der Daten auf die Partitionen zu gewährleisten.
- "Heiße Daten", also Daten, auf die häufig zugegriffen wird, sollten in von den "kalten Daten" getrennten Tabellen gespeichert werden.
- Ein Verständnis der zu erwartenden Abfragemuster vor der Erstellung der Datenbank ermöglicht eine optimale Gestaltung von Sortierschlüsseln und Indizes.
Speicherung von großen Attributwerten
- Für große Attributwerte wird die Verwendung von Kompressionstechniken empfohlen, um den Speicherbedarf zu reduzieren.
- Bei sehr großen Datenmengen können bestimmte Attribute in Amazon S3 ausgelagert und nur der Pfad in DynamoDB gespeichert werden.
- Große Attribute sollten auf mehrere Items verteilt werden, um die Grenze von 400 Kilobyte pro Item nicht zu überschreiten.
Leseoperationen
- Scans und Filter können die Ressourcen stark belasten und hohe Kosten verursachen. Es wird empfohlen, gezielte Abfragen mit Indizes zu verwenden.
- Um die Kosten für Lesevorgänge zu reduzieren, bei denen die Echtzeitkonsistenz nicht kritisch ist, kann die mögliche Konsistenz genutzt werden.
Lokale Sekundärindizes (LSI)
- Lokale Sekundärindizes sollten sparsam eingesetzt werden, da sie die Ressourcenbelastung erhöhen können
- Eine begrenzte Speicherung von Attributen in einem LSI hilft, die Größe des Index zu begrenzen.
Globale Sekundärindizes (GSI)
- Auch bei GSIs ist eine begrenzte Speicherung von Attributen sinnvoll, um eine effiziente Abfrage zu gewährleisten.
GSIs sind gut geeignet, um möglicherweise konsistente Lese-Replikate einer Dynamo DB Tabelle zu erstellen, um die Last auf der Haupttabelle zu reduzieren.
Fazit
AWS DynamoDB ist eine robuste, hochskalierbare NoSQL-Datenbank für moderne Cloud-Anwendungen. Mit flexibler Datenmodellierung, ACID-Transaktionsunterstützung und verschiedenen Konsistenzmodellen bietet sie eine Plattform für vielseitige Anwendungen. Dynamische Preismodelle, effizientes Schlüsseldesign und der intelligente Einsatz von Indizes ermöglichen eine kosteneffiziente Skalierung. Dennoch sollten bei der Erstellung von DynamoDB-Tabellen wichtige Faktoren wie die richtige Wahl von Primär- und Sortierschlüsseln sowie die richtige Definition von Indizes beachtet werden, um eine effiziente Nutzung zu gewährleisten und eine Kostenexplosion zu vermeiden.