Azure Tables

Massendaten in der Microsoft Cloud (Teil 2)
Kommentare

Windows Developer

Der Artikel „Azure Tables“ von Rainer Stropek ist erstmalig erschienen im Windows Developer 8.2012
Struktur von Table Services
In Windows Azure können Sie abhängig vom Typ Ihrer

Windows Developer

Der Artikel „Azure Tables“ von Rainer Stropek ist erstmalig erschienen im Windows Developer 8.2012

Struktur von Table Services

In Windows Azure können Sie abhängig vom Typ Ihrer Subscription eine gewisse Anzahl an Storage Accounts anlegen. Das geschieht in der Regel über das Windows-Azure-Verwaltungsportal [1]. Alternativ können Sie das Anlegen von Storage Accounts auch über PowerShell [2] automatisieren. Je Storage Account legen Sie anschließend Ihre Tabellen an und können sie dann mit Daten füllen. Für das Verwalten der Tabellen und der enthaltenen Daten steht auf unterster Ebene ein REST-basiertes API zur Verfügung. In Ihren Programmen werden Sie jedoch mit großer Wahrscheinlichkeit nicht direkt die REST-Aufrufe, sondern eine der Client-Libraries (z. B. für .NET, iOS, PHP, Node.js etc.) verwenden. Leider bietet Microsoft zum aktuellen Zeitpunkt kein Werkzeug für die interaktive Verwaltung von Tabellen und Daten an. Wenn Sie mehr mit Table Services arbeiten, empfiehlt es sich daher in der Praxis, ein entsprechendes Drittanbieterprodukt zu kaufen. Der Platzhirsch unter diesen Tools ist meiner Erfahrung nach das Cloud Storage Studio von Cerebrata [3].

Tabellen in Table Services haben im Gegensatz zu einer relationalen Datenbank kein Schema. Jedes Entity (jede Zeile) kann unterschiedliche Properties (Eigenschaften) haben. Beachten Sie dazu Abbildung 1. Sie sehen eine Tabelle, bei der die letzten beiden Zeilen eine Eigenschaft Address haben, die bei den anderen Kunden fehlt. Die zweite Zeile repräsentiert eine Kundenbestellung und hat völlig andere Eigenschaften als alle anderen Zeilen. Besondere Bedeutung kommt den linken drei Eigenschaften zu:

Abb. 1: Eigenschaften in einer Tabelle
Abb. 1: Eigenschaften in einer Tabelle
  • PartitionKey und RowKey: Diese beiden Eigenschaften bilden gemeinsam den Primärschlüssel der Tabelle. Sie müssen bei jeder Zeile gesetzt werden und haben den Datentyp String (max. Größe jeweils 1 Kilobyte). Bedenken Sie bei der Wahl der Werte für diese Eigenschaften, dass der Primärschlüssel auch gleichzeitig der einzige Index in Ihrer Tabelle ist (sekundäre Indizes wie bei SQL Azure gibt es in Table Services im Moment nicht) und daher dem häufigsten Suchkriterium bei Abfragen entsprechen sollte.
  • Timestamp: Datum und Uhrzeit der letzten Änderung des Datensatzes. Sie dürfen diesen Wert weder explizit schreiben noch sollten Sie ihn in Ihrer Programmlogik lesen. Microsoft behält es sich vor, die Bedeutung dieses Wertes in der Zukunft zu verändern.

Besondere Aufmerksamkeit sollten Sie der Vergabe des Wertes für PartitionKey widmen, da er ausschlaggebend für die Skalierbarkeit und Verfügbarkeit von Transaktionen ist. In Sachen Skalierbarkeit steuert er, welche Datensätze der Tabelle immer gemeinsam gespeichert und verarbeitet werden. Aus Tabelle 1 haben Sie bereits erfahren, dass Table Services automatisch nach dem Scale-Out-Ansatz skalieren: Bei sehr vielen Zugriffen auf Ihre Tabelle werden die Daten und auch die Zugriffe darauf auf mehrere Server aufgeteilt. Die Daten einer Partition bleiben jedoch beisammen.

Was Transaktionen betrifft ist die PartitionKey-Eigenschaft wichtig, da Transaktionen nur innerhalb einer Partition möglich sind. Sie können beispielsweise nicht in einer Transaktion Zeilen mit unterschiedlichen Werten für PartitionKey einfügen.

Bei kleinen Tabellen brauchen Sie sich in der Regel keine Gedanken über Partitionen zu machen; verwenden Sie ruhig den gleichen PartitionKey-Wert für alle Zeilen. Bei großen Tabellen gilt es, eine Partitionsbezeichnung zu wählen, die Ihrer Zugriffs- und Transaktionsstruktur entgegen kommt. Ein Beispiel: Sie möchten das Log für Ihre Webanwendung in Table Services speichern. Es wird mit der Zeit sehr groß werden und es ist möglich, dass unter Hochlast viele tausend Log-Einträge pro Sekunde gespeichert werden müssen. Wie würden Sie den Partition– und RowKey wählen? Hier einige kommentierte Varianten dazu:

  • Alle Zeilen in eine Partition (d. h. PartitionKey ist konstant), Log-Zeitpunkt als RowKey: die wahrscheinlich schlechteste Wahl. Sie würden nicht von der automatischen Skalierung profitieren, da alle Zeilen in einer Partition gespeichert werden. Außerdem kann es bei Parallelverarbeitung (z. B. in einer Webfarm) zu Fehlern wegen doppelter Schlüsseleinträge kommen, da der Log-Zeitpunkt nicht garantiert eindeutig wäre.
  • Jahr/Monat/Tag als PartitionKey, Log-Zeitpunkt als RowKey: ebenfalls keine optimale Variante. Wenn unter Hochlast viele Zeilen gleichzeitig geschrieben werden, betreffen sie alle den gleichen Tag; man profitiert wieder nicht von der automatischen Skalierung.
  • Webservername als PartitionKey, Log-Zeitpunkt als RowKey: Das ist keine schlechte Wahl, wenn man davon ausgeht, dass bei steigender Last dynamisch in der Cloud neue Webserver gestartet werden. Diese Partitionslogik würde auch Abfrageszenarien verbessern, bei der ein Administrator gezielt nach Fehlern auf einem bestimmten Webserver in einem bestimmten Zeitraum sucht. Fehler wegen doppelter Schlüsseleinträge wären jedoch auch hier nicht auszuschließen; diese könnte man jedoch durch Anhängen einer eindeutigen ID (z. B. GUID) ausschließen.

Natürlich wären viele weitere Varianten denkbar. Die drei Beispiele sollen aber illustrieren, nach welchen Kriterien Sie bei der Festlegung der beiden Primärschlüsselspalten vorgehen können. Vergessen Sie bei Ihren Überlegungen aber nicht, dass die Länge der Schlüsselspalten auch den zu bezahlenden Speicherbedarf beeinflusst (siehe dazu auch Kasten „Berechnung des Speicherverbrauchs“).

Berechnung des Speicherverbrauchs

Da nicht alle Zeilen in einer Tabelle die gleichen Eigenschaften (Spalten) haben müssen, sind die Table Services gezwungen, in jeder Zeile zu speichern, welche Eigenschaften sie enthält. Insofern beeinflusst die Namensgebung der Eigenschaften den Speicherverbrauch. Obwohl die Kosten pro Gigabyte im Bereich der Table Services sehr gering sind, kann sich ein langer Eigenschaftsname bei Tabellen mit entsprechend großer Anzahl an Zeilen doch bemerkbar machen. Die Größe einer Zeile in einer Tabelle in Bytes kann nach folgender Formel berechnet werden:

Größe der Zeile in Bytes =
4 Bytes
+ (Länge von PartitionKey und RowKey) * 2
+ Summe für alle Eigenschaften nach folgender Formel:
8 Bytes
+ (Länge des Eigenschaftsnamen) * 2
+ Größe des .NET-Datentyps der Zeile in Bytes

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -