Schema entwerfen

Auf dieser Seite wird erklärt, wie Sie ein Schema für eine Tabelle in Cloud Bigtable erstellen. Bevor Sie diese Seite lesen, sollten Sie sich mit dem Überblick über Cloud Bigtable vertraut machen.

Allgemeine Konzepte

Ein Schema für Cloud Bigtable zu entwerfen unterscheidet sich stark davon, ein Schema für eine relationale Datenbank zu entwickeln. Beim Entwerfen Ihres Schemas für Cloud Bigtable sind folgende Konzepte bedeutend:

  • Jede Tabelle verfügt nur über einen Index, den Zeilenschlüssel. Es gibt keinen Sekundärindex.
  • Zeilen werden lexikografisch geordnet, von der niedrigsten bis zur höchsten Bytezahl. Zeilenschlüssel werden in Big-Endian oder Network Byte Order, dem binären Äquivalent der alphabetischen Reihenfolge, geordnet.
  • Alle Operationen auf der Zeilenebene sind atomisch. Wenn Sie zum Beispiel 2 Zeilen in einer Tabelle aktualisieren, ist es möglich, dass eine erfolgreich aktualisiert wird und die andere nicht. Schemas, die Atomarität zwischen Zeilen benötigen, sollten vermieden werden.
  • Lesen und Schreiben sollten bestenfalls gleichmäßig verteilt sein über die Zeilen der Tabelle.
  • Grundsätzlich sollten sich alle Informationen für eine Entität in einer einzelnen Zeile befinden. Eine Entität, die keine atomaren Aktualisierungen und Lesevorgänge benötigt, kann auf mehrere Zeilen aufteilt werden. Das Aufteilen auf mehrere Zeilen ist zu empfehlen, wenn die Datenmenge der Entität groß ist (hunderte von MB).
  • Verwandet Entitäten sollten in angrenzenden Zeilen gespeichert werden, um Lesevorgänge effizienter zu gestalten.
  • Tabellen in Cloud Bigtable sind klein. Leere Spalten nehmen keinen Platz ein. Daher ist es oft sinnvoll, viele Spalten zu erstellen, auch wenn die meisten Spalten in den meisten Zeilen leer sind.

Größenbeschränkungen

Eine bewährte Methode ist es, beim Entwerfen des Schemas unter diesen empfohlenen Größenbeschränkungen zu bleiben.

  • Zeilenschlüssel: 4 KB pro Schlüssel
  • Spaltenfamilie: ~100 Familien pro Tabelle
  • Spaltenqualifizierer: 16 KB pro Qualifizierer
  • Individuelle Werte: ~10 MB pro Zelle
  • Alle Werte in einer einzelnen Zeile: ~100 MB

Zusätzlich darf der Entwurf des Schemas folgende echte Grenzen nicht überschreiten:

  • Individuelle Werte: 100 MB pro Zelle
  • Alle Werte in einer einzelnen Zeile: 256 MB
  • Tabellen: 1.000 pro Cluster

Zeilen werden atomisch gelesen, Daher ist es besonders wichtig, die gesamte Datenmenge auf eine einzelne Zeile zu beschränken. Wenn Sie beispielsweise versuchen, 25 Zeilen zu lesen, die jeweils 100 MB an Daten enthalten, und Ihre Instanz nur über 2 GB RAM verfügt, werden Sie einen Fehler wegen fehlendem Platz im Arbeitsspeicher auslösen.

Zeilenschlüssel wählen

Um die beste Leistung aus Cloud Bigtable herauszuholen, ist es entscheidend, dass Sie gründlich darüber nachdenken, wie Sie Ihren Zeilenschlüssel bilden wollen. Das liegt daran, da die meisten effizienten Abfragen in Cloud Bigtable den Zeilenschlüssel, ein Zeilenpräfix oder einen Zeilenbereich verwenden, um Daten zu erhalten. Andere Arten von Abfragen lösen einen Scan der gesamten Tabelle aus, was deutlich weniger effizient ist. Durch die Wahl des korrekten Zeilenschlüssels jetzt können Sie einen schmerzhaften Datenmigrationsprozess später verhindern.

Anfangs stellt sich die Fragen, wie Sie die Daten, die Sie speichern wollen, verwenden werden. Beispiel:

  • Nutzerinformationen: Brauchen Sie schnellen Zugang zu Informationen über die Verbindungen zwischen Nutzern (beispielsweise, ob Nutzer A Nutzer B folgt)?
  • Nutzergenerierte Inhalte: Wenn Sie Nutzern eine Auswahl an viel nutzergeneriertem Inhalt, wie Statusaktualisierungen, zeigen, wie entscheiden Sie, welche Statusaktualisierung Sie dem Nutzer anzeigen?
  • Zeitachsendaten: Werden Sie oft die letzten N Datensätze oder die Datensätze, die in ein bestimmtes Zeitfenster fallen, benötigen? Falls Sie Daten für verschiedene Ereignisse sammeln, müssen Sie nach Art des Ereignisses filtern?

Durch das Verständnis für Ihre Bedürfnisse im Vorhinein, können Sie sicher gehen, dass Ihr Zeilenschlüssel und der gesamte Entwurf Ihres Schemas genug Flexibilität bieten, um Ihre Daten effizient abzufragen.

Arten von Zeilenschlüsseln

In diesem Teil werden einige der am häufigsten verwendeten Arten von Zeilenschlüsseln beschrieben und wann Sie welchen verwenden sollten, erklärt.

Als Faustregel gilt, den Zeilenschlüssel angemessen kurz zu halten. Lange Zeilenschlüssel nehmen mehr Arbeits- und Festplattenspeicher in Anspruch. Sie erhöhen auch die Zeit, bis Cloud Bigtable eine Antwort ausgibt.

Umgekehrte Domainnamen

Sollten Sie Daten über Entitäten, die als Domainnamen dargestellt werden können, lagern, ziehen Sie es in Betracht einen umgekehrten Domainnamen als Zeilenschlüssel zu verwenden (zum Beispiel: com.company.product). Einen umgekehrten Domainnamen zu verwenden ist besonders dann eine gute Idee, wenn die Daten in jeder Zeile dazu neigen, sich mit benachbarten Zeilen zu überschneiden. In diesem Fall kann Cloud Bigtable Ihre Daten besser komprimieren.

Diese Herangehensweise funktioniert am besten, wenn Ihre Daten über viele verschiedene umgekehrte Domainnamen verteilt sind. Wenn Sie davon ausgehen, den Großteil Ihrer Daten in wenigen umgekehrten Domainnamen zu speichern, ziehen Sie andere Werte für Ihre Zeilenschlüssel in Betracht. Andernfalls könnten Sie eine Tabellenreihe überladen, indem Sie die meisten Schreibvorgänge auf einen einzelnen Knoten in Ihrem Cluster schieben.

Stringidentifizierer

Wenn Sie Daten über Entitäten, die mit einem einfachen String identifiziert werden können (beispielsweise Nutzer-IDs), speichern, sollten Sie den Stringidentifizierer möglicherweise als Zeilenschlüssel oder als Teil des Zeilenschlüssels verwenden. Ziehen Sie in Betracht, einen Hash des Identifizierers, statt dem Identifizierer selbst zu verwenden, sodass der Identifizierer über eine voraussehbare Länge verfügt. Einen Hash zu verwenden hilft besonders dann, wenn Sie mehrere Werte zu einem einzigen Zeilenschlüssel kombinieren, wie unten beschrieben.

Zeitstempel

Wenn Sie oft Daten basierend auf der Zeit abrufen wollen, zu der sie aufgenommen wurden, dann ist es eine gute Idee, einen Zeitstempel in Ihren Zeilenschlüssel zu integrieren. Den Zeilenschlüssel für sich als Zeilenschlüssel zu verwenden, wird nicht empfohlen, da die meisten Schreibvorgänge auf einen Knoten geschoben werden würden. Aus dem gleichen Grund sollten Sie es vermeiden, den Zeitstempel als Beginn des Zeilenschlüssels zu nutzen.

Ihre Anwendung könnte beispielsweise leistungsbezogene Daten, wie CPU- und Speicherauslastung, einmal pro Sekunde für eine große Zahl an Maschinen aufzeichnen. Ihr Zeilenschlüssel für diese Daten könnte aus einer Kombination einer Kennung für die Maschine und einem Zeitstempel für die Daten bestehen (zum Beispiel: machine_4223421#1425330757685).

Wenn Sie normalerweise die am kürzesten zurückliegenden Aufzeichnungen zuerst erhalten, können Sie einen umgekehrten Zeitstempel im Zeilenschlüssel verwenden, indem Sie den Zeitstempel von dem Maximalwert für lange Ganzzahlen Ihrer Programmiersprache abziehen (in Java java.lang.Long.MAX_VALUE). Mit einem umgekehrten Zeitstempel werden die Aufzeichnung von der letzten bis zur ersten geordnet.

Mehrere Werte in einem einzelnen Zeilenschlüssel

Da die einzige Möglichkeit für effiziente Abfragen in Cloud Bigtable der Zeilenschlüssel ist, ist es oft sinnvoll mehrere Identifizierer in Ihren Zeilenschlüssel einzubeziehen. Wenn Ihr Zeilenschlüssel mehrere Werte beinhaltet, ist es besonders wichtig, eine klares Verständnis von der Verwendung der Daten zu haben.

Angenommen, Ihre Anwendung erlaubt es Nutzern, Nachrichten zu posten und sich gegenseitig in Beiträgen zu erwähnen. Sie wollen einen effizienten Weg, alle Nutzer aufzulisten, die einen bestimmten Nutzer in einem Post getaggt haben. Eine Möglichkeit, dieses Ziel zu erreichen, besteht darin, einen Zeilenschlüssel zu verwenden, der einen Hash des getaggten Nutzernamens gefolgt von einem Hash des taggenden Nutzernamens beinhaltet. In jeder Zeile wären die ungehashten Nutzernamen zusammen mit den Daten des Posts gespeichert:

Eine Cloud Bigtable Tabelle, deren Zeilenschlüssel die gehashte Version zweier Nutzernamen kombiniert.

Um herauszufinden, wer einen bestimmten Nutzernamen getaggt hat oder um alle Posts anzuzeigen, die diesen Nutzernamen taggen, können Sie einfach die Reihe an Zeilen abrufen, deren Zeilenschlüssel mit diesem Nutzernamen beginnen.

Wie im Beispiel gezeigt, ist es wichtig einen Zeilenschlüssel zu erstellen, der Ihnen noch erlaubt, eine gut definierte Reihe an Zeilen abzufragen. Andernfalls benötigen Ihre Abfragen einen Tabellenscan, der viel länger als das Abrufen bestimmter Zeilen dauert. Angenommen, Sie lagern leistungsbezogene Daten einmal pro Sekunde. Wenn Ihr Zeilenschlüssel aus einem Zeitstempel gefolgt von einem Maschinenidentifizierer (zum Beispiel 1425330757685#machine_4223421) besteht, gäbe es keinen effizienten Weg, Ihre Abfrage auf eine bestimmte Maschine zu beschränken. Sie könnten Ihre Abfrage nur basierend auf dem Zeitstempel beschränken.

Zu vermeidende Zeilenschlüssel

Manche Arten von Zeilenschlüsseln können Schwierigkeiten beim Abfragen Ihrer Daten verursachen oder die Leistung beeinträchtigen. In diesem Teil werden einige Arten von Zeilenschlüsseln beschrieben, deren Verwendung Sie in Cloud Bigtable vermeiden sollten.

Domainnamen

Vermeiden Sie standardmäßige, nicht umgekehrte Domain-Namen als Zeilenschlüssel. Die Verwendung von standardmäßigen Domainnamen macht die Abfrage aller Zeilen innerhalb eines Teils der Domain ineffektiv (beispielsweise alle Zeilen mit Bezug zu company.com werden sich in separaten Zeilenbereichen wie services.company.com und product.company.com befinden, etc.) Zudem verursacht die Verwendung von standardmäßigen Domainnamen, dass Zeilen so sortiert werden, dass Daten mit Bezug zueinander nicht an einem Ort gespeichert werden. Dies kann zu einer weniger effizienten Komprimierung führen.

Sequenzielle numerische ID

Angenommen, Ihr System vergibt eine numerische ID an jeden Nutzer Ihrer Anwendung. Es mag verlockend klingen, die numerische ID der Nutzer als Zeilenschlüssel für Ihre Tabelle zu verwenden. Da neue Nutzer jedoch wahrscheinlich aktiver sind, verschiebt diese Herangehensweise den Großteil Ihres Traffics auf wenige Knoten.

Eine sicherere Herangehensweise wäre es, eine umgekehrte Version der numerischen ID der Nutzer zu verwenden. Dadurch verteilt sich der Traffic gleichmäßiger auf die Knoten Ihrer Tabelle in Cloud Bigtable.

Statische, wiederholt aktualisierte Identifizierer

Vermeiden Sie die Verwendung eines einzelnen Zeilenschlüssels zur Identifizierung eines Wertes, der sehr oft aktualisiert werden muss. Wenn Sie beispielsweise Daten zur Speichernutzung einmal pro Sekunde speichern, verwenden Sie keinen einzelnen Zeilenschlüssel mit dem Namen memusage und aktualisieren Sie die Zeile nicht wiederholt. Diese Art von Operation überlädt die Tabellenreihe, die die häufig verwendete Zeile speichert. Sie kann auch dazu führen, dass eine Zeile Ihr Größenlimit überschreitet, da die vorherigen Werte der Zelle eine Weile Platz einnehmen.

Speichern Sie stattdessen einen Wert pro Zeile, indem Sie einen Zeilenschlüssel verwenden, der die Art des Messwerts, einen Delimiter und einen Zeitstempel beinhaltet. Um Speichernutzung über Zeit zu überwachen, können Sie Zeilenschlüssel ähnlich wie memusage#1423523569918 verwenden. Diese Strategie ist effizient, weil es in Cloud Bigtable länger dauert, eine neue Zeile zu erstellen, als eine neue Zelle. Zusätzlich können Sie durch diese Strategie schnell Daten aus einem speziellen Datenbereich lesen, indem Sie die passenden Start- und Endschlüssel berechnen.

Für Werte, die sich sehr häufig ändern, wie zum Beispiel ein Zähler, der sich hunderte Male pro Minute aktualisiert, ist es am besten, die Daten im Speicher zu lassen, auf der Anwendungsebene, und periodisch neue Zeilen in Cloud Bigtable zu schreiben.

Spaltenfamilien und Spaltenqualifizierer

In diesem Teil finden Sie eine Anleitung darüber, wie Spaltenfamilien und -qualifizierer in Ihrer Tabelle behandelt werden sollten.

Spaltenfamilien

In Cloud Bigtable, anders als in HBase, können Sie bis zu ~100 Spaltenfamilien bei exzellenter Leistung verwenden. Daher ist es ein bewährtes Verfahren, die verwandten Werte einer Zeile in die gleiche Spaltenfamilie zu gruppieren. Dies erlaubt es Ihnen, Daten aus einer einzelnen Familie oder aus mehreren Familien, statt die Daten einer ganzen Zeile, abzufragen. Gruppieren Sie Daten so nah wie möglich miteinander, um in Ihren häufigsten API-Abfragen genau die Informationen zu erhalten, die Sie brauchen, aber nicht mehr.

Auch sollten die Namen Ihrer Spaltenfamilien kurz sein, da sie in den für die Abfragen gesendeten Daten enthalten sind.

Spaltenqualifizierer

Da Cloud Bigtable Tabellen rar sind, können sie so viele Spaltenqualifizierer in jeder Zeile erstellen, wie Sie brauchen. Es gibt keine Platzstrafe für leere Zellen in einer Zeile. Daher ist es oft sinnvoll Spaltenqualifizierer als Daten zu behandeln. Wenn Ihr Tabelle beispielsweise Nutzerbeiträge beinhaltet, könnten Sie den einzigartigen Identifizierer für jeden Post als Spaltenqualifizierer verwenden.

Wie bei Zeilenschlüsseln und Spaltenfamilien empfiehlt es sich, die Namen der Spaltenqualifizierer kurz zu halten. Dies hilft dabei, die Datenmenge, die bei jeder Abfrage transferiert wird, klein zu halten.

Hohe oder breite Tabellen

Die Beispiele, die Sie bisher gesehen haben, zeigen breite Tabellen, in denen eine einzelne Zeile eine hohe Anzahl an Spalten beinhaltet. Typischerweise erhalten Sie eine breite Tabelle, wenn Sie Spaltenqualifizierer als Daten verwenden. Es gibt auch Fälle, in denen es sinnvoll ist, eine hohe Tabelle zu verwenden, die über eine große Anzahl an Zeilen und wenige Spalten pro Zeile verfügt.

Schauen wir und das Prezzy-Beispiel aus dem Überblick nochmal an:

Eine breite Tabelle mit vielen Spalten für jeden Nutzernamen.

Dieses Beispiel ist eine breite Tabelle, die aufzeichnet, wem jeder Nutzer folgt. Für jeden Nutzer beinhaltet die Tabelle eine Spalte pro folgendem Nutzer.

Angenommen, Sie brauchen nicht die komplette Liste von Nutzern, denen die Nutzer folgen. Stattdessen wollen Sie Cloud Bigtable verwenden, um eine engere Frage zu beantworten: Folgt Nutzer A Nutzer B?

Eine effiziente Lösung für diesen Fall besteht darin, eine hohe Tabelle mit einer Zeile pro Beziehung zwischen Folgendem und Gefolgtem zu verwenden. Der Zeilenschlüssel für die hohe Tabelle kombiniert Hashes der Nutzernamen des Folgenden und des Gefolgten. Als Ergebnis können Sie überprüfen, ob Nutzer A Nutzer B folgt, indem Sie noch einem einzigen Zeilenschlüssel suchen. Falls die Zeile vorhanden ist, folgt Nutzer A Nutzer B, falls nicht, folgt Nutzer A nicht Nutzer B.

Hier ist die Version der Prezzy-Daten mit hoher Tabelle:

Eine hohe Tabelle mit einer Zeile für jede folgende Beziehung.

Falls Sie wissen wollen, ob der Nutzer jadams dem Nutzer tjefferson folgt, können Sie einfach nach dem Zeilenschlüssel suchen, der den Hash von jadams (df887e44) mit dem Hash von tjefferson (b0452e5c) kombiniert. Die Zeile df887e44b0452e5c ist vorhanden. Daher wissen wir, dass jadamstjefferson folgt.

Beachten Sie, dass die hohe Tabelle Nutzernamen von jedem Nutzer, dem gefolgt wird, speichert. Ohne diese Information wäre es sehr zeitaufwendig, den Nutzernamen zu finden, der dem Hash entspricht.

Mehr erfahren

Weitere Informationen zum Speichern von Daten, die über Zeit aufgenommen werden: Schema-Entwurf für Zeitachsendaten.

Feedback geben zu...

Cloud Bigtable-Dokumentation