In diesem Dokument werden Best Practices für die Verwendung von Spanner als primäre Back-End-Datenbank zum Speichern von Spielstatus. Sie können Spanner anstelle von gemeinsamen Datenbanken, um Spielerauthentifizierungsdaten und Inventar zu speichern Daten. Dieses Dokument richtet sich an Entwickler von Spiele-Back-Ends, die langfristig arbeiten. Zustandsspeicherung und Spielinfrastrukturbetreiber und -administratoren, die diese unterstützen, und möchten ihre Back-End-Datenbank auf Google Cloud
Für Spiele mit Mehrspielermodus und Onlinespiele sind immer komplexere Datenbankstrukturen erforderlich, um Spielerberechtigungen, Status und Inventardaten zu verfolgen. Die wachsende Spielerbasis und die zunehmende Komplexität der Spiele haben zu Datenbanklösungen geführt, deren Skalierung und Verwaltung eine Herausforderung darstellt und bei denen häufig eine Fragmentierung oder ein Clustering notwendig sind. Damit wertvolle In-Game-Elemente oder wichtige Spielerfortschritte verfolgt werden können, sind in der Regel Transaktionen erforderlich. Bei vielen Arten verteilter Datenbanken lässt sich das nur schwer umgehen.
Spanner ist der erste global verteilte Datenbankdienst mit strikter Konsistenz für Unternehmen, der für die Cloud entwickelt wurde und die Vorteile einer relationalen Datenbankstruktur mit nicht relationaler horizontaler Skalierung vereint. Zahlreiche Spieleunternehmen setzen den Dienst bereits ein, da er sich gut eignet, um in Produktionsumgebungen Datenbanken für Spielstatus und solche für Authentifizierung zu ersetzen. Mit der Google Cloud Console können Sie zur Skalierung Knoten hinzufügen und so die Leistung oder den Speicherplatz erhöhen. Spanner kann die globale Replikation transparent mit strikter Konsistenz handhaben, sodass Sie regionale Replikate nicht mehr verwalten müssen.
Dieses Best Practices-Dokument behandelt folgende Themen:
- Wichtige Konzepte von Spanner und Unterschiede zu Datenbanken, die häufig in Spielen verwendet werden
- Wann Spanner die richtige Datenbank für Ihr Spiel ist
- Muster, die Sie beim Einsatz von Spanner für Spiele vermeiden sollten
- Gestaltung Ihrer Datenbankvorgänge mit Spanner als Datenbank für Ihr Spiel
- Modellierung von Daten und Erstellung eines Schemas mit dem Ziel, mit Spanner die Leistung zu optimieren
Terminologie
- Berechtigungen
- Spiele, Erweiterungen oder In-App-Käufe eines Spielers.
- Personenidentifizierbare Informationen (personally identifiable information, PII)
- Bei Spielen gehören zu diesen Informationen in der Regel die E-Mail-Adresse und Angaben zum Zahlungskonto wie eine Kreditkartennummer und eine Rechnungsadresse. In einigen Märkten können diese Informationen auch eine nationale Ausweisnummer umfassen.
- Spieledatenbank (Spiele-DB)
- Eine Datenbank, die den Spielerfortschritt und das Inventar für ein Spiel enthält.
- Authentifizierungsdatenbank (Auth-DB)
- Eine Datenbank mit Spielerberechtigungen und den personenidentifizierbaren Informationen, die die Spieler beim Kauf verwenden. Die Authentifizierungsdatenbank wird auch als Konto- oder Spielerdatenbank bezeichnet. Diese Datenbank wird manchmal mit der Datenbank des Spiels kombiniert, bei Studios oder Publishern mit mehreren Titeln wird sie jedoch häufig getrennt.
- Transaktion
- Eine Datenbanktransaktion, d. h. ein Satz von Schreibvorgängen mit Alles-oder-Nichts-Effekt. Die Transaktion ist entweder erfolgreich und alle Aktualisierungen werden wirksam oder die Datenbank wird in einen Status zurückgesetzt, der keine Aktualisierung der Transaktion enthält. Bei Spielen sind Datenbanktransaktionen bei der Verarbeitung von Zahlungen und beim Zuweisen der Eigentümerschaft von In-Game-Inventar oder -Währung entscheidend.
- Managementsystem für relationale Datenbanken (relational database management system, RDBMS)
- Ein Datenbanksystem, das auf Tabellen und Zeilen basiert, die aufeinander verweisen. SQL Server, MySQL und (seltener) Oracle® sind Beispiele für relationale Datenbanken, die bei Spielen zum Einsatz kommen. Diese werden häufig verwendet, weil sie vertraute Methoden und zuverlässige Garantien für Transaktionen bieten können.
- NoSQL-Datenbank (NoSQL-DB)
- Datenbanken, die nicht relational strukturiert sind. Diese Datenbanken werden immer beliebter bei Spielen, da sie sehr flexibel sind, wenn sich das Datenmodell ändert. Zu den NoSQL-Datenbanken gehören MongoDB und Cassandra.
- Primärschlüssel
- Normalerweise die Spalte mit der eindeutigen ID für Inventar-Items, Spielerkonten und Kauftransaktionen.
- Instanz
- Eine einzelne Datenbank. Ein Cluster führt beispielsweise mehrere Kopien der Datenbanksoftware, wird aber im Spiele-Back-End als einzelne Instanz angezeigt.
- Knoten
- In diesem Dokument ein einzelner Computer, auf dem eine Kopie der Datenbanksoftware ausgeführt wird.
- Replikat
- Eine zweite Kopie einer Datenbank. Replikate werden häufig für die Datenwiederherstellung und Hochverfügbarkeit verwendet oder erhöhen den Lesedurchsatz.
- Cluster
- Mehrere Kopien der Software, die auf vielen Computern ausgeführt werden und die zusammen werden im Back-End des Spiels als einzelne Instanz angezeigt. Clustering dient der Skalierbarkeit und Verfügbarkeit.
- Shard
- Eine Instanz einer Datenbank. Viele Spielestudios führen mehrere homogene Datenbankinstanzen aus, von denen jede einen Teil der Spieldaten enthält. Eine einzelne solche Instanz wird als Shard bezeichnet. Sharding bzw. eine Fragmentierung erfolgt in der Regel aus Gründen der Leistung oder Skalierbarkeit. Dabei ergeben sich Effizienzeinbußen bei der Verwaltung und die Anwendung wird komplexer. Die Fragmentierung in Spanner wird mithilfe von Splits umgesetzt.
- Split
- Spanner teilt Ihre Daten in Portionen auf, die sogenannten Splits. Dabei können einzelne Splits unabhängig voneinander verschoben und verschiedenen Servern zugewiesen werden. Ein Split wird als eine Reihe von Zeilen in einer übergeordneten (mit anderen Worten: nicht verschränkten) Tabelle definiert, wobei die Zeilen nach Primärschlüssel geordnet sind. Die Start- und Endschlüssel dieses Bereichs werden als "Split-Grenzen" bezeichnet. Spanner fügt automatisch Split-Grenzen hinzu und entfernt sie, was die Anzahl der Splits in der Datenbank verändert. Spanner teilt Daten nach Last auf: Es fügt Split-Grenzen automatisch hinzu, wenn eine hohe Lese- oder Schreiblastverteilung über mehrere Schlüssel in einem Split erkannt wird.
- Hotspot
- Ein Hotspot ist ein einzelner Split in einer verteilten Datenbank wie Spanner, der über Datensätze verfügt, die einen großen Teil aller an die Datenbank gestellten Abfragen erhalten. Hotspot-Szenarien gilt es zu vermeiden, da sie die Leistung beeinträchtigen.
Einsatz von Spanner für Spiele
In den meisten Fällen, in denen ein RDBMS für ein Spiel zum Einsatz kommen soll, ist Spanner die richtige Wahl, denn der Dienst kann entweder die Spieledatenbank, die Authentifizierungsdatenbank oder in vielen Fällen beide ersetzen.
Spieledatenbanken
Spanner kann als eine einzige weltweite Transaktionsstelle fungieren und eignet sich daher hervorragend für Inventarsysteme von Spielen. In umfangreichen Spiele-Back-Ends stellt jede Währung und jedes Item, das gehandelt, verkauft, verschenkt oder anderweitig von einem Spieler auf einen anderen übertragen werden kann, eine Herausforderung dar. Wenn ein Spiel besonders populär ist, reicht die herkömmliche Datenbank, die alles auf einem einzigen Knoten verarbeiten kann, häufig nicht aus. Je nach Art des Spiels kann die Datenbank schon durch die Anzahl der Vorgänge, die für die Verarbeitung von Spielerlasten erforderlich sind, stark beansprucht sein. Aber auch die Menge der gespeicherten Daten kann ihr zu schaffen machen. Deshalb fragmentieren Spieleentwickler häufig ihre Datenbank für zusätzliche Leistung oder speichern ständig wachsende Tabellen. Diese Art von Lösung sorgt dann jedoch für einen komplexeren Betrieb und einen hohen Wartungsaufwand.
Eine verbreitete Strategie zur Vermeidung dieser Komplexität besteht darin, vollständig getrennte Spielregionen auszuführen. Dabei geht die Möglichkeit verloren, Daten zwischen ihnen zu verschieben. In diesem Fall können Items und Währungen also nicht zwischen Spielern in verschiedenen Spielregionen gehandelt werden, da das Inventar in jeder Region in separate Datenbanken aufgeteilt wird. Dieses Setup macht es dem Entwickler leichter und den Betrieb des Spiels einfacher, vernachlässigt aber das bevorzugte Spielererlebnis.
Andererseits können Sie den Handel über Regionen hinweg in einer geografisch fragmentierten Datenbank zulassen. Das ist jedoch häufig mit hoher Komplexität verbunden. Bei diesem Setup müssen Transaktionen mehrere Datenbankinstanzen durchlaufen, was auf der Anwendungsseite zu einer komplexen, fehleranfälligen Logik führt. Wenn Sie für mehrere Datenbanken Transaktionssperren erreichen möchten, kann sich das erheblich auf die Leistung auswirken. Sich nicht auf atomare Transaktionen verlassen zu können, kann darüber hinaus zu Spieler-Exploits wie der Duplizierung von Währung oder Items im Spiel sorgen, und das schadet der Umgebung und der Community des Spiels.
Spanner kann den Ansatz bei Transaktionen von Inventar und Währung vereinfachen. Auch wenn Sie Spanner zum Speichern Ihrer gesamten Spiele verwenden bietet es Lese-Schreib-Transaktionen mit sogar stärker als die herkömmliche Atomarität, Konsistenz, Isolation und Langlebigkeit (ACID) Eigenschaften. Dank der Skalierbarkeit von Spanner muss nicht in separate Datenbankinstanzen aufgeteilt werden, Leistung oder Speicher benötigt wird; können Sie weitere Knoten hinzufügen. Darüber hinaus werden die hohe Verfügbarkeit und Robustheit der Daten, für die Datenbanken von Spielen häufig in Clustern zusammengefasst werden, von Cloud Spanner transparent gehandhabt, sodass keine zusätzliche Einrichtung oder Verwaltung erforderlich ist.
Authentifizierungsdatenbanken
Auch Authentifizierungsdatenbanken können gut von Spanner bereitgestellt werden. Das gilt insbesondere, wenn Sie auf Studio- oder Publisher-Ebene standardmäßig ein einzelnes RDBMS anbieten möchten. Obwohl Authentifizierungsdatenbanken für Spiele häufig nicht die Größe brauchen, die Spanner bietet, können die Transaktionsgarantien und die hohe Datenverfügbarkeit der Anwendung in bestimmten Fällen ein schlagendes Argument sein. Die Datenreplikation ist in Spanner integriert und erfolgt transparent und synchron. Der Dienst bietet Konfigurationen mit einer Verfügbarkeit von 99,99 % ("viermal die Neun") oder 99,999 % ("fünfmal die Neun"), wobei die "fünfmal die Neun"-Konfiguration weniger als fünfeinhalb Minuten Nichtverfügbarkeit in einem Jahr entspricht. Diese Art der Verfügbarkeit macht Cloud Spanner zu einer guten Wahl für den entscheidenden Authentifizierungspfad, den jeder Spieler zu Beginn einer Sitzung gehen muss.
Best Practices
Dieser Abschnitt enthält Empfehlungen zur Verwendung von Spanner im Spieledesign. Damit Sie von den einzigartigen Features von Spanner profitieren können, ist es wichtig, dass Sie die Spieldaten entsprechend modellieren. Zwar ist es möglich, mit der Semantik von relationalen Datenbanken auf Spanner zuzugreifen, einige Punkte im Schemadesign können aber zur Leistungssteigerung beitragen. Spanner Dokumentation hat detaillierte Empfehlungen zum Schemadesign die Sie sich ansehen können. In den folgenden Abschnitten finden Sie jedoch einige Best Practices Datenbanken
Die Methoden in diesem Dokument basieren auf Erfahrungen aus Kundenanwendungen und Fallstudien.
UUIDs als Spieler- und Charakter-IDs verwenden
Die Spielertabelle enthält in der Regel eine Zeile für jeden Spieler sowie die Währung, den Fortschritt oder andere Daten im Spiel, die sich nicht leicht zu einzelnen Tabellenzeilen für Inventar zuordnen lassen. Wenn Spieler bei einem Spiel für mehrere Charaktere den Fortschritt separat speichern können, wie bei vielen großen Massive-Multiplayer-Games möglich, enthält diese Tabelle dann in der Regel eine Zeile für jeden Charakter. Ansonsten ist das Muster gleich.
Es empfiehlt sich, als Primärschlüssel der Charaktertabelle eine global eindeutige Charakter- oder Spielerkennung (Charakter-ID) zu verwenden. Außerdem sollten Sie die UUID (Universally Unique Identifier) in der Version 4 verwenden. Diese verteilt die Spielerdaten auf Datenbankknoten und trägt so dazu bei, dass Spanner eine höhere Leistung erbringen kann.
Verschränkung für Inventartabellen verwenden
Die Inventartabelle enthält häufig In-Game-Elemente wie Charakterausrüstung, Karten oder Einheiten. In der Regel hat ein einzelner Spieler zahlreiche Items in seinem Inventar. Jedes Item wird durch eine einzelne Zeile in der Tabelle dargestellt.
Ähnlich wie bei anderen relationalen Datenbanken hat eine Inventartabelle in Spanner einen Primärschlüssel, der eine global eindeutige Kennung für das Item ist, wie in der folgenden Tabelle dargestellt.
itemID
|
type
|
playerID
|
---|---|---|
7c14887e-8d45 |
1 |
6f1ede3b-25e2 |
8ca83609-bb93 |
40 |
6f1ede3b-25e2 |
33fedada-3400 |
1 |
5fa0aa7d-16da |
e4714487-075e |
23 |
5fa0aa7d-16da |
d4fbfb92-a8bd |
14 |
5fa0aa7d-16da |
31b7067b-42ec |
3 |
26a38c2c-123a |
In der Inventartabelle aus dem Beispiel sind itemID
und playerID
zur besseren Lesbarkeit abgeschnitten. Eine echte Inventartabelle hätte noch viele andere Spalten, die im Beispiel nicht enthalten sind.
Wenn es darum geht, die Eigentümerschaft der Items zu verfolgen, wird in einem RDBMS üblicherweise eine Spalte als Fremdschlüssel verwendet, die die Spieler-ID des aktuellen Eigentümers enthält. Diese Spalte ist der Primärschlüssel einer separaten Datenbanktabelle. In Spanner können Sie Verschränkungen verwenden. Dabei werden die Inventarzeilen in der Nähe der zugehörigen Zeile in der Spielertabelle gespeichert, um die Leistung zu verbessern. Wenn Sie verschränkte Tabellen verwenden, sollten Sie Folgendes beachten:
- Ohne Eigentümer können Sie kein Objekt erstellen. Eigentümerlose Objekte lassen sich im Spieledesign vermeiden, wenn die Beschränkung im Voraus bekannt ist.
Indexierung gestalten, um Hotspots zu vermeiden
Viele Spieleentwickler implementieren Indexe für viele der Inventarfelder, um bestimmte Abfragen zu optimieren. In Spanner erzeugt das Erstellen oder Aktualisieren einer Zeile mit Daten in diesem Index eine zusätzliche Schreiblast, die der Anzahl der indexierten Spalten entspricht. Hier können Sie die Leistung von Spanner verbessern: Entfernen Sie dafür eher selten verwendete Indexe oder implementieren Sie diese Indexe auf andere Weise, sodass sie sich nicht auf die Datenbankleistung auswirken.
Im folgenden Beispiel gibt es eine Tabelle mit Highscore-Einträgen von Langzeitspielern:
CREATE TABLE Ranking (
PlayerID STRING(36) NOT NULL,
GameMode INT64 NOT NULL,
Score INT64 NOT NULL
) PRIMARY KEY (PlayerID, GameMode)
Diese Tabelle enthält die Spieler-ID (UUIDv4), eine Zahl, die einen Spielmodus, eine Phase oder eine Staffel sowie die Punktzahl des Spielers darstellt.
Zum Beschleunigen von Abfragen, die nach dem Spielmodus filtern, setzen Sie den folgenden Index ein:
CREATE INDEX idx_score_ranking ON Ranking (
GameMode,
Score DESC
)
Wenn jeder den gleichen Spielmodus, nämlich 1
, spielt, entsteht bei diesem Index ein Hotspot bei GameMode=1
. Wenn Sie für diesen Spielmodus eine Rangfolge abrufen möchten, durchsucht der Index nur die Zeilen mit GameMode=1
und gibt die Rangfolge schnell zurück.
Dieses Problem können Sie lösen, wenn Sie die Reihenfolge des vorherigen Index ändern:
CREATE INDEX idx_score_ranking ON Ranking (
Score DESC,
GameMode
)
Bei diesem Index entsteht durch Spieler, die im gleichen Spielmodus gegeneinander spielen, kein bedeutender Hotspot. Voraussetzung dafür ist aber, dass ihre Punktzahlen über den möglichen Bereich verteilt sind. Das Abrufen von Punktzahlen erfolgt dann jedoch nicht so schnell wie beim vorherigen Index, da die Abfrage alle Punktzahlen aus allen Modi scannt, um zu ermitteln, ob GameMode=1
ist.
Der Index mit neuer Reihenfolge löst also das Hotspot-Problem beim Spielmodus. Trotzdem besteht Verbesserungsbedarf, wie im folgenden Design veranschaulicht:
CREATE TABLE GameMode1Ranking (
PlayerID STRING(36) NOT NULL,
Score INT64 NOT NULL
) PRIMARY KEY (PlayerID)
CREATE INDEX idx_score_ranking ON Ranking (
Score DESC
)
Sie sollten den Spielmodus aus dem Tabellenschema herausnehmen und falls möglich pro Modus eine Tabelle verwenden. Wenn Sie mit dieser Methode die Punktzahlen für einen Modus abrufen, wird nur eine Tabelle mit Punktzahlen für diesen Modus abgefragt. Diese Tabelle kann nach Punktzahl indexiert werden und Punktzahlbereiche lassen sich auf diese Weise schnell abrufen, ohne dass Hotspots entstehen (vorausgesetzt, die Punktzahlen sind gut verteilt). Zum Zeitpunkt der Abfassung des dieses Dokument maximale Anzahl von Tabellen pro Datenbank in Spanner beträgt 2.560, was für die meisten Spiele mehr als ausreichend ist.
Separate Datenbanken pro Mandant
Im Gegensatz zu anderen Arbeitslasten, empfiehlt ein Design für Mehrmandantenfähigkeit in Spanner mit unterschiedlichen Primärschlüsselwerten. Für Spieldaten empfehlen wir, herkömmlicher Ansatz mit separaten Datenbanken pro Mandant. Bei der Veröffentlichung neuer Features in Echtzeit-Spielen gibt es häufig Schemaänderungen. Wenn Mandanten auf Datenbankebene isoliert werden, kann dies Schemaaktualisierungen vereinfachen. Mit dieser Strategie lässt sich auch die Zeit optimieren, die für die Sicherung oder Wiederherstellung eines da diese Vorgänge für eine ganze Datenbank einmal.
Inkrementelle Schemaaktualisierungen vermeiden
Im Gegensatz zu manchen konventionellen relationalen Datenbanken bleibt Spanner während der Schemaaktualisierung funktionsfähig. Alle Abfragen für das alte Schema werden zurückgegeben, wobei dies etwas länger als üblich dauern kann. Abfragen für das neue Schema werden zurückgegeben, sobald sie verfügbar sind. Sie können den Aktualisierungsvorgang so gestalten, dass das Spiel, wenn es auf Spanner läuft, während der Schemaaktualisierung weiter ausgeführt wird – wenn Sie dabei die oben genannten Einschränkungen beachten.
Wenn Sie jedoch eine weitere Schemaänderung anfordern, verarbeitet wurde, wird das neue Update in die Warteschlange gestellt und erst dann durchgeführt, wenn alle vorherigen Schemaaktualisierungen sind abgeschlossen. Dies können Sie vermeiden, wenn Sie größere Schemaaktualisierungen planen, statt in kurzer Zeit viele inkrementelle Schemaaktualisierungen durchzuführen. Weitere Informationen zu Schemaaktualisierungen, einschließlich der Ausführung von Schemaaktualisierungen mit erforderlicher Datenvalidierung, finden Sie in der Dokumentation zu Spanner-Schemaaktualisierungen.
Datenbankzugriff und -größe berücksichtigen
Wenn Sie einen Spieleserver und Plattformdienste für die Verwendung von Spanner entwickeln, achten Sie darauf, wie das Spiel auf die Datenbank zugreift und welche Größe die Datenbank haben sollte, um unnötige Kosten zu vermeiden.
Integrierte Treiber und Bibliotheken verwenden
Berücksichtigen Sie bei der Entwicklung für Spanner, wie der Code mit der Datenbank interagiert. Spanner bietet integrierte Clientbibliotheken für viele beliebte Sprachen, die in der Regel funktionsreich und leistungsstark sind. Außerdem gibt es JDBC-Treiber, die Anweisungen in der Datenbearbeitungssprache (Data Manipulation Language, DML) und der Datendefinitionssprache (Data Definition Language, DDL) Wenn Spanner im Rahmen von Neuentwicklungen verwendet wird, empfiehlt sich der Einsatz der Cloud-Clientbibliotheken für Spanner. Typische Integrationen von Spiel-Engines sind bei der Sprachauswahl zwar nicht sehr flexibel, es gibt bei Plattformdiensten, die auf Spanner zugreifen, aber Gaming-Kunden, die Java oder Go verwenden. Bei Anwendungen mit hohem Durchsatz sollten Sie daher eine Bibliothek auswählen, in der Sie denselben Spanner-Client für mehrere sequenzielle Anfragen verwenden können.
Größe der Datenbank auf Test- und Produktionsanforderungen abstimmen
Während der Entwicklung reicht wahrscheinlich eine Spanner-Instanz mit einem Knoten für die meisten Aktivitäten, auch Funktionstests, aus.
Anforderungen an Spanner für die Produktion evaluieren
Wenn Sie nach der Entwicklung zur Testphase und anschließend zur Produktion übergehen, ist eine neue Evaluierung Ihrer Anforderungen an Spanner wichtig, damit Ihr Spiel die Live-Spielerzahlen bewältigen kann.
Bevor Sie zur Produktion übergehen, sind unbedingt Lasttests durchzuführen, um zu überprüfen, ob Ihr Back-End die Last während der Produktion verarbeiten kann. Dabei sollten Sie Lasttests mit der doppelten Last durchführen, die Sie in der Produktion erwarten. So sind Sie auf Auslastungsspitzen ebenso wie auf den Fall vorbereitet, dass Ihr Spiel bei der Beliebtheit Ihre Erwartungen übertrifft.
Lasttests mit realen Daten ausführen
Einen Belastungstest mit synthetische Daten reicht nicht aus. Sie sollten außerdem Lasttests mit Daten und Zugriffsmustern durchführen, die sich möglichst nahe an den Erwartungen in der Produktion bewegen. Mit synthetischen Daten sind möglicherweise auch potenzielle Hotspots im Schemadesign für Spanner nicht zu erkennen. Am besten ist ein (offener oder geschlossener) Betatest mit echten Spielern. Denn so können Sie prüfen, wie sich Spanner bei echten Daten verhält.
Das folgende Diagramm ist ein Beispiel für ein Spielertabellenschema eines Spielestudios, das beispielhaft zeigt, wie wichtig Betatests für das Testen von Lasten sind.
Das Spielestudio hat anhand von Trends eines vorherigen Spiels, das es einige Jahre lang betrieben hatte, diese Daten vorbereitet. Das Unternehmen ging davon aus, dass die Daten mit diesem Schema im neuen Spiel gut dargestellt würden.
Mit jedem Spielerdatensatz sind einige numerische Attribute verknüpft, die den Fortschritt des Spielers im Spiel darstellen (z. B. Rang und Spielzeit). Für das in der vorhergehenden Tabelle verwendete Beispielattribut erhalten neue Spieler einen Startwert von 50. Dieser Wert ändert sich dann im Laufe des Spiels auf einen Wert zwischen 1 und 100.
Das Studio möchte für dieses Attribut einen Index erstellen, um wichtige Abfragen während des Spiels zu beschleunigen.
Auf Grundlage dieser Daten erstellte das Studio die folgende Spanner-Tabelle mit einem Primärschlüssel. Dafür wurden die PlayerID
und ein sekundärer Index für Attribute
verwendet.
CREATE TABLE Player (
PlayerID STRING(36) NOT NULL,
Attribute INT64 NOT NULL
) PRIMARY KEY (PlayerID)
CREATE INDEX idx_attribute ON Player(Attribute)
Der Index wurde so abgefragt, um bis zu zehn Spieler mit Attribute=23
zu finden:
SELECT PlayerID
FROM Player@{force_index=idx_attribute}
WHERE Attribute = 23
LIMIT 10
Gemäß der Dokumentation zum Optimieren von Schemadesigns speichert Spanner Indexdaten auf dieselbe Weise wie Tabellen mit einer Zeile pro Indexeintrag. In Lasttests zeigt dieses Modell eine akzeptable Leistung bei der Verteilung der Lese- und Schreiblast des sekundären Index auf mehrere Spanner-Splits. Dies ist im folgenden Diagramm dargestellt:
Obwohl die synthetischen Daten aus dem Lasttest dem endgültigen stabilen Zustand des Spiels mit einer guten Verteilung der Attribute
-Werte nahekommen, sieht das Spieldesign vor, dass alle Spieler mit Attribute=50
beginnen. Da jeder neue Spieler mit Attribute=50
beginnt, werden neue Spieler in den gleichen Teil des sekundären Indexes, nämlich idx_attribute
, eingefügt. Das bedeutet, dass Aktualisierungen an denselben Spanner-Split weitergeleitet werden, wodurch während des Startfensters des Spiels ein Hotspot entsteht. Dies ist eine ineffiziente Verwendung von Spanner.
Das folgende Diagramm illustriert, wie das Hotspot-Problem durch Hinzufügen einer IndexPartition
-Spalte zum Schema nach dem Start gelöst wird, wodurch die Spieler gleichmäßig auf die verfügbaren Spanner-Splits verteilt werden. Der aktualisierte Befehl zum Erstellen der Tabelle und des Index sieht so aus:
CREATE TABLE Player (
PlayerID STRING(36) NOT NULL,
IndexPartition INT64 NOT NULL
Attribute INT64 NOT NULL
) PRIMARY KEY (PlayerID)
CREATE INDEX idx_attribute ON Player(IndexPartition,Attribute)
Der Wert IndexPartition
muss einen begrenzten Bereich für effiziente Abfragen haben.
Er sollte aber auch einen Bereich haben, der mindestens doppelt so hoch ist wie die Anzahl der Splits für
effiziente Verteilung vor.
In diesem Fall hat das Studio jedem Spieler in der Spieleanwendung manuell eine IndexPartition
zwischen 1
und 6
zugewiesen.
Alternativ könnte jedem Spieler eine Zufallszahl oder ein Wert zugewiesen werden, der sich aus einem Hash zum Wert PlayerID
ableitet.
Siehe Was Datenbankadministratoren über Spanner wissen müssen, Teil 1: Schlüssel und Indexe
für Fragmentierungsstrategien auf Anwendungsebene.
So lässt sich die vorherige Abfrage aktualisieren, um diesen verbesserten Index zu verwenden:
SELECT PlayerID
FROM Player@{force_index=idx_attribute}
WHERE IndexPartition BETWEEN 1 and 6
AND Attribute = 23
LIMIT 10
Da kein Betatest durchgeführt wurde, bemerkte das Studio nicht, dass die Tests auf Daten mit falschen Annahmen beruhten. Synthetische Lasttests sind zwar um zu prüfen, wie viele Abfragen pro Sekunde (Queries per Second, QPS) die Instanz verarbeitet, ist ein Betatest mit echten Spielern erforderlich, Schema erstellen und eine erfolgreiche Einführung vorbereiten.
Produktionsumgebung für Spitzennachfrage skalieren
Große Spiele haben meist den größten Traffic zu verzeichnen, wenn sie herauskommen. Aufbau eines Skalierbares Back-End gilt nicht nur für Plattformdienste und dedizierte Spiele sondern auch für Datenbanken. Mit Google Cloud-Lösungen wie App Engine Frontend-API-Dienste erstellen, die schnell hochskaliert werden können. Obwohl Sie bei Spanner flexibel Knoten online hinzufügen und entfernen können, ist der Dienst keine Datenbank mit Autoscaling. Sie müssen genügend Knoten bereitstellen, um die Zugriffsspitzen beim Start zu bewältigen.
Anhand der während des Lasttests oder auch bei öffentlichen Betatests gesammelten Daten können Sie die Anzahl der Knoten abschätzen, die Sie beim Start zum Verarbeiten von Anfragen brauchen. Dabei empfiehlt es sich, einige Knoten als Puffer zu ergänzen, falls Sie mehr Spieler als erwartet haben. Die Datenbank sollte immer so dimensioniert werden, dass eine durchschnittliche CPU-Auslastung von 65 % nicht überschritten wird.
Datenbank vor dem Start des Spiels aufwärmen
Bevor Sie Ihr Spiel starten, sollten Sie Ihre Datenbank aufwärmen, um die Spanner-Parallelisierungsfunktionen zu nutzen. Weitere Informationen finden Sie unter Datenbank vor dem Anwendungsstart aufwärmen.
Leistung beobachten und nachvollziehen
Jede Produktionsdatenbank braucht umfangreiche Messwerte für die Überwachung und Leistung. Spanner hat integrierte Messwerte in Cloud Monitoring. Wenn möglich, empfehlen wir, die bereitgestellten gRPC-Bibliotheken in Back-End-Prozesses, da diese Bibliotheken OpenCensus Tracing Mit OpenCensus Tracing können Sie Abfrage-Traces in Cloud Trace sowie in anderen unterstützten Open Source-Tracing-Tools ansehen.
In Cloud Monitoring werden Details zur Nutzung von Spanner, einschließlich der Datenspeicherung und CPU-Auslastung, angezeigt. In den meisten Fällen empfiehlt es sich, bei der Entscheidung zur Skalierung von Spanner auf diesen Messwert zur CPU-Nutzung oder die beobachtete Latenz zurückzugreifen. Weitere Informationen zu empfohlene CPU-Nutzung für eine optimierte Leistung, siehe Best Practices.
Spanner bietet Abfrageausführungspläne. Sie können diese Pläne in der Cloud Console überprüfen. Bei Bedarf hilft Ihnen der Support, Ihre Abfrageleistung nachzuvollziehen.
Wenn Sie eine Leistungsbewertung vornehmen, sollten Sie Kurzzeittests auf ein Minimum beschränken, da Spanner die Daten im Hintergrund transparent aufteilt, um die Leistung anhand Ihrer Datenzugriffsmuster zu optimieren. Die Leistung sollten Sie mithilfe von dauerhaften, realistischen Abfragelasten evaluieren.
Beim Entfernen von Daten Zeilen löschen, statt Tabellen neu zu erstellen
Wenn Sie mit Spanner arbeiten, hatten neu erstellte Tabellen noch keine Gelegenheit, last- oder größenbasierte Aufteilungen durchzuführen, um die Leistung zu verbessern. Wenn Sie Daten löschen, indem Sie eine Tabelle entfernen, und dann eine neue Tabelle erstellen, braucht Spanner Daten, Abfragen und Zeit, um die korrekten Splits für die Tabelle zu ermitteln. Wenn Sie eine Tabelle mit der gleichen Art von Daten neu füllen möchten, was zum Beispiel bei aufeinanderfolgenden Leistungstests der Fall sein kann, können Sie stattdessen eine DELETE
-Abfrage für die Zeilen ausführen, die nicht mehr benötigte Daten enthalten. Aus demselben Grund sollte bei Schemaaktualisierungen auf die bereitgestellte Cloud Spanner API zurückgegriffen werden. Außerdem sollten Sie hier eine manuelle Strategie, wie das Erstellen einer neuen Tabelle und das Kopieren der Daten aus einer anderen Tabelle oder einer Sicherungsdatei, vermeiden.
Aufbewahrungsort für Daten auswählen, um Complianceanforderungen zu erfüllen
Viele Spiele müssen Gesetze zum Speicherort von Daten wie die DSGVO wenn sie weltweit gespielt werden. Weitere Informationen zur Einhaltung der DSGVO finden Sie in der Whitepaper zur Google Cloud und zur DSGVO und wählen Sie die richtige Regionale Spanner-Konfiguration.
Nächste Schritte
- So setzte Bandai Namco Entertainment Spanner beim erfolgreichen Start von Dragon Ball Legends ein
- Cloud Next '18-Session zur Optimierung von Anwendungen, Schemas und dem Abfragedesign in Spanner ansehen
- Anleitung zur Migration von DynamoDB zu Spanner