Best practice per l'utilizzo di Cloud Spanner come database per i videogiochi

Questo documento descrive le best practice per l'utilizzo di Spanner come database di backend principale per l'archiviazione dello stato dei giochi. Puoi utilizzare Spanner al posto dei database comuni per archiviare i dati di autenticazione dei giocatori e i dati di inventario. Questo documento è rivolto ai tecnici del backend di gioco che lavorano all'archiviazione a lungo termine dello stato, nonché agli operatori e agli amministratori dell'infrastruttura di gioco che supportano questi sistemi e sono interessati a ospitare il proprio database di backend su Google Cloud.

I giochi multiplayer e online si sono evoluti fino a richiedere strutture di database sempre più complesse per monitorare i diritti dei giocatori, lo stato e i dati di inventario. La crescita della base di giocatori e l'aumento della complessità del gioco hanno portato a soluzioni di database difficili da scalare e gestire, che richiedono spesso l'uso di sharding o clustering. Il monitoraggio di elementi in-game preziosi o dei progressi critici dei giocatori in genere richiede transazioni ed è difficile da gestire in molti tipi di database distribuiti.

Spanner è il primo servizio di database scalabile di livello enterprise a elevata coerenza e distribuito su scala globale, pensato per il cloud allo scopo di combinare i vantaggi della struttura di database relazionale con la scalabilità orizzontale non relazionale. Molte aziende produttrici di videogiochi si sono rivelate particolarmente adatte a sostituire i database di stato e di autenticazione nei sistemi di produzione. Puoi scalare per ottenere ulteriori prestazioni o spazio di archiviazione utilizzando la console Google Cloud per aggiungere nodi. Spanner può gestire in modo trasparente la replica globale con elevata coerenza, eliminando la necessità di gestire le repliche a livello di regione.

Questo documento di best practice illustra i seguenti argomenti:

  • Concetti importanti di Spanner e le differenze rispetto ai database comunemente usati nei giochi.
  • Quando Spanner è il database giusto per il tuo gioco.
  • Pattern da evitare quando si utilizza Spanner per i giochi.
  • Progettare le operazioni di database usando Spanner come database del gioco.
  • Modellazione dei dati e creazione di uno schema per ottenere le migliori prestazioni con Spanner.

Terminologia

Entitlement
Giochi, espansioni o acquisti in-app appartenenti a un giocatore.
Informazioni che consentono l'identificazione personale (PII)
Nei giochi, informazioni che in genere includono l'indirizzo email e i dati dell'account per i pagamenti, come il numero di carta di credito e l'indirizzo di fatturazione. In alcuni mercati, queste informazioni potrebbero includere il numero del documento di identità.
Database di giochi (DB di gioco)
Un database contenente i progressi dei giocatori e l'inventario di un gioco.
Database di autenticazione (DB di autenticazione)
Un database che include i diritti dei giocatori e le PII che i giocatori utilizzano quando effettuano un acquisto. Il DB di autenticazione è anche noto come DB account o DB del player. Questo database viene talvolta combinato con il database di gioco, ma spesso è separato in studi o editori che hanno più titoli.
Transazione
Una transazione del database: un insieme di operazioni di scrittura con un effetto tutto o niente. La transazione ha esito positivo e tutti gli aggiornamenti vengono applicati oppure il database viene restituito a uno stato che non include nessuno degli aggiornamenti della transazione. Nei giochi, le transazioni dei database sono fondamentali nell'elaborazione dei pagamenti e nell'assegnazione della proprietà di valuta o inventario in-game di valore.
Sistema di gestione di database relazionali (RDBMS)
Un sistema di database basato su tabelle e righe che fanno riferimento l'una all'altra. SQL Server, MySQL e (meno comunemente) Oracle® sono esempi di database relazionali utilizzati nei giochi. Vengono utilizzati spesso perché possono fornire metodologie familiari e forti garanzie per le transazioni.
Database NoSQL (DB NoSQL)
Database che non sono strutturati in modo relazionale. Questi database stanno diventando più popolari nei giochi perché offrono molta flessibilità quando il modello dei dati cambia. I database NoSQL includono MongoDB e Cassandra.
Chiave primaria
Di solito è la colonna che contiene l'ID univoco per gli articoli dell'inventario, gli account giocatore e le transazioni di acquisto.
Istanza
Un unico database. Ad esempio, un cluster esegue più copie del software del database, ma appare come una singola istanza per il backend del gioco.
Nodo
Ai fini del presente documento, una singola macchina che esegue una copia del software del database.
Replica
Una seconda copia di un database. Le repliche vengono utilizzate spesso per il recupero dei dati e l'alta disponibilità o per aumentare la velocità effettiva di lettura.
Cluster
Più copie del software in esecuzione su molte macchine che insieme vengono visualizzate come un'unica istanza nel backend del gioco. Il clustering è utilizzato per la scalabilità e la disponibilità.
Shard
Un'istanza di un database. Molte case di produzione giochi eseguono più istanze di database omogenee, ognuna delle quali contiene un sottoinsieme dei dati di gioco. Ognuna di queste istanze è comunemente definita shard. Lo sharding viene in genere eseguito per le prestazioni o la scalabilità, sacrificando l'efficienza di gestione e aumentando al contempo la complessità dell'app. Lo sharding in Spanner viene implementato utilizzando split.
Suddividi
Spanner suddivide i dati in blocchi denominati split, dove le singole suddivisioni possono spostarsi in modo indipendente l'una dall'altra ed essere assegnate a server diversi. Una suddivisione è definita come un intervallo di righe in una tabella di primo livello (in altre parole, senza interleaving), in cui le righe sono ordinate per chiave primaria. Le chiavi iniziale e finale di questo intervallo sono chiamate "confini della suddivisione". Spanner aggiunge e rimuove automaticamente i confini della suddivisione, cambiando così il numero di suddivisioni nel database. Spanner suddivide i dati in base al carico: aggiunge automaticamente confini della suddivisione quando rileva un carico elevato di lettura o scrittura tra molte chiavi in una suddivisione.
Hotspot
Quando una singola suddivisione in un database distribuito come Spanner contiene record che ricevono una grande parte di tutte le query inviate al database. Questo scenario non è consigliabile perché le prestazioni peggiorano.

Utilizzo di Spanner per i giochi

Nella maggior parte dei casi in cui si prende in considerazione un RDBMS per il proprio gioco, Spanner è una scelta appropriata perché può sostituire in modo efficace il database di gioco, il database auth o, in molti casi, entrambi.

Database di gioco

Spanner può operare come un'unica autorità transazionale a livello mondiale, il che lo rende ideale per i sistemi di inventario dei giochi. Qualsiasi valuta o articolo in-game che può essere scambiato, venduto, regalato o altrimenti trasferito da un giocatore all'altro rappresenta una sfida nei backend dei giochi su larga scala. Spesso, la popolarità di un gioco può superare la capacità di un database tradizionale di gestire tutto in un database a nodo singolo. A seconda del tipo di gioco, il database può avere difficoltà con il numero di operazioni necessarie per gestire il carico del player e la quantità di dati memorizzati. Questo spesso porta gli sviluppatori di giochi a eseguire lo sharding del loro database per migliorare le prestazioni o ad archiviare tabelle in costante crescita. Questo tipo di soluzione porta a complessità operativa e costi di manutenzione elevati.

Per ridurre questa complessità, una strategia comune prevede l'esecuzione di regioni di gioco completamente separate, senza alcun modo di spostare dati da una all'altra. In questo caso, gli articoli e la valuta non possono essere scambiati tra i giocatori in regioni di gioco diverse, perché gli inventari di ogni regione sono separati in database separati. Tuttavia, questa configurazione sacrifica l'esperienza preferita del giocatore, a favore dello sviluppo e della semplicità operativa.

D'altra parte, è possibile consentire scambi tra regioni in un database geograficamente segmentato, ma spesso a un costo di complessità elevato. Questa configurazione richiede che le transazioni raggiungano più istanze di database, il che genera una logica lato applicazioni complessa e soggetta a errori. Provare a ottenere blocchi delle transazioni su più database può avere un impatto significativo sulle prestazioni. Inoltre, l'impossibilità di fare affidamento sulle transazioni atomiche può portare a exploit dei giocatori come la valuta in-game o la duplicazione di articoli, che danneggiano l'ecosistema e la community del gioco.

Spanner può semplificare l'approccio alle transazioni di inventario e valuta. Anche quando viene utilizzato Spanner per conservare tutti i dati dei tuoi giochi in tutto il mondo, offre transazioni di lettura e scrittura con proprietà ancora più potenti delle tradizionali proprietà di atomicità, coerenza, isolamento e durabilità (ACID). Con la scalabilità di Spanner, non è necessario eseguire lo sharding dei dati in istanze di database separate quando sono necessarie prestazioni o spazio di archiviazione maggiori; puoi invece aggiungere altri nodi. Inoltre, l'alta disponibilità e la resilienza dei dati per cui i giochi spesso eseguono il clustering dei propri database vengono gestite in modo trasparente da Spanner, senza bisogno di ulteriori configurazioni o gestione.

Database autorizzazioni

I database Auth possono anche essere ben gestiti da Spanner, soprattutto se vuoi standardizzare su un singolo RDBMS a livello di studio o di publisher. Sebbene i database di autenticazione per i giochi spesso non richiedano la scalabilità di Spanner, le garanzie transazionali e l'elevata disponibilità dei dati possono renderla convincente. La replica dei dati in Spanner è trasparente, sincrona e integrata. Spanner ha configurazioni che offrono una disponibilità del 99,99% ("quattro nove") o del 99,999% ("cinque nove"), dove "cinque nove" corrispondono a meno di cinque minuti e mezzo di indisponibilità in un anno. Questo tipo di disponibilità lo rende una buona scelta per il percorso di autenticazione critico richiesto all'inizio di ogni sessione del player.

Best practice

Questa sezione fornisce suggerimenti su come utilizzare Spanner nella progettazione di giochi. È importante modellare i dati dei giochi per sfruttare le funzionalità uniche offerte da Spanner. Sebbene sia possibile accedere a Spanner utilizzando la semantica del database relazionale, alcuni punti di progettazione dello schema possono aiutarti ad aumentare le prestazioni. La documentazione di Spanner contiene suggerimenti dettagliati sulla progettazione dello schema che puoi esaminare, ma le sezioni seguenti sono alcune best practice per i database di gioco.

Le pratiche riportate in questo documento si basano sulle esperienze relative all'utilizzo dei clienti e ai case study.

Utilizza gli UUID come ID player e carattere

La tabella dei giocatori ha in genere una riga per ogni giocatore e la valuta in-game, l'avanzamento o altri dati che non vengono mappati facilmente alle righe della tabella dell'inventario discreto. Se il gioco consente ai giocatori di salvare separatamente i progressi salvati per più personaggi, ad esempio molti giochi multiplayer permanenti di grandi dimensioni, in genere questa tabella contiene una riga per ogni personaggio. In caso contrario, il pattern è lo stesso.

Ti consigliamo di utilizzare un carattere o un identificatore giocatore (ID carattere) univoci a livello globale come chiave primaria nella tabella di caratteri. Ti consigliamo inoltre di utilizzare Universally Unique Identifier (UUID) v4, perché consente di distribuire i dati dei player tra i nodi DB e di ottimizzare le prestazioni di Spanner.

Utilizzare l'interfoliazione per le tabelle dell'inventario

La tabella dell'inventario spesso contiene elementi in-game, come equipaggiamento dei personaggi, carte o unità. In genere, un singolo giocatore ha molti elementi nel suo inventario. Ogni elemento è rappresentato da una singola riga nella tabella.

Analogamente ad altri database relazionali, una tabella di inventario in Spanner ha una chiave primaria che rappresenta un identificatore univoco globale per l'elemento, come illustrato nella tabella seguente.

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

Nella tabella dell'inventario di esempio, i valori itemID e playerID sono troncati per facilitarne la leggibilità. Una tabella di inventario effettiva contiene anche molte altre colonne non incluse nell'esempio.

Un approccio tipico in un RDBMS per il monitoraggio della proprietà degli elementi consiste nell'utilizzare una colonna come chiave esterna contenente l'ID player dell'attuale proprietario. Questa colonna è la chiave primaria di una tabella di database separata. In Spanner, puoi utilizzare l'interleaving, che archivia le righe dell'inventario vicino alla riga della tabella del player associata per migliorare le prestazioni. Quando utilizzi le tabelle con interleaving, tieni presente quanto segue:

  • Non puoi generare un oggetto senza un proprietario. Puoi evitare gli oggetti senza proprietario nella struttura del gioco, a patto che la limitazione sia nota in anticipo.

Progetta l'indicizzazione per evitare gli hotspot

Molti sviluppatori di giochi implementano indici in molti campi dell'inventario per ottimizzare determinate query. In Spanner, la creazione o l'aggiornamento di una riga contenente dati al suo interno genera un carico di scrittura aggiuntivo proporzionale al numero di colonne indicizzate. Puoi migliorare le prestazioni di Spanner eliminando gli indici che non vengono utilizzati di frequente o implementando questi indici in altri modi che non influiscono sulle prestazioni del database.

Nell'esempio seguente, è disponibile una tabella per i record dei punteggi migliori dei giocatori a lungo termine:

CREATE TABLE Ranking (
        PlayerID STRING(36) NOT NULL,
        GameMode INT64 NOT NULL,
        Score INT64 NOT NULL
) PRIMARY KEY (PlayerID, GameMode)

Questa tabella contiene l'ID giocatore (UUIDv4), un numero che rappresenta una modalità di gioco, fase o stagione e il punteggio del giocatore.

Per velocizzare le query che filtrano per la modalità di gioco, considera il seguente indice:

CREATE INDEX idx_score_ranking ON Ranking (
        GameMode,
        Score DESC
)

Se tutti utilizzano la stessa modalità di gioco chiamata 1, questo indice crea un hotspot in cui GameMode=1. Se vuoi ottenere un ranking per questa modalità di gioco, l'indice analizza solo le righe contenenti GameMode=1, restituendo rapidamente il ranking.

Modificando l'ordine dell'indice precedente, puoi risolvere questo problema relativo all'hotspot:

CREATE INDEX idx_score_ranking ON Ranking (
        Score DESC,
        GameMode
)

Questo indice non creerà un hotspot significativo per i giocatori che competono nella stessa modalità di gioco, a condizione che i loro punteggi siano distribuiti nell'intervallo possibile. Tuttavia, i punteggi non saranno veloci come con l'indice precedente, perché la query analizza tutti i punteggi da tutte le modalità per determinare se GameMode=1.

Di conseguenza, l'indice riordinato risolve l'hotspot precedente in modalità di gioco ma ha comunque un margine di miglioramento, come illustrato nel design che segue.

CREATE TABLE GameMode1Ranking (
        PlayerID STRING(36) NOT NULL,
        Score INT64 NOT NULL
) PRIMARY KEY (PlayerID)

CREATE INDEX idx_score_ranking ON Ranking (
        Score DESC
)

Consigliamo di rimuovere la modalità di gioco dallo schema della tabella e di utilizzare una tabella per modalità, se possibile. Utilizzando questo metodo, quando recuperi i punteggi per una modalità, esegui una query solo su una tabella con i punteggi per quella modalità. Questa tabella può essere indicizzata per punteggio per un rapido recupero degli intervalli di punteggio senza il pericolo significativo di hotspot (a condizione che i punteggi siano ben distribuiti). Al momento della stesura di questo documento, il numero massimo di tabelle per database in Spanner è 2560, un valore più che sufficiente per la maggior parte dei giochi.

Database separati per tenant

A differenza di altri carichi di lavoro, per cui consigliamo di progettare per l'architettura multi-tenancy in Spanner utilizzando coppie chiave-valore primarie diverse, per i dati di gioco raccomandiamo l' approccio più convenzionale di database separati per tenant. Le modifiche allo schema sono comuni con il rilascio di nuove funzionalità dei giochi nei giochi di servizi live e l'isolamento dei tenant a livello di database può semplificare gli aggiornamenti dello schema. Questa strategia consente anche di ottimizzare il tempo necessario per il backup o il ripristino dei dati di un tenant, perché queste operazioni vengono eseguite su un intero database contemporaneamente.

Evita gli aggiornamenti incrementali dello schema

A differenza di alcuni database relazionali convenzionali, Spanner rimane operativo durante gli aggiornamenti dello schema. Tutte le query sullo schema precedente vengono restituite (anche se potrebbero essere restituite meno rapidamente del solito) e le query sul nuovo schema vengono restituite non appena diventano disponibili. Puoi progettare il processo di aggiornamento in modo da mantenere il gioco in esecuzione durante gli aggiornamenti dello schema quando viene eseguito su Spanner, a condizione di tenere presenti i vincoli precedenti.

Tuttavia, se richiedi un'altra modifica allo schema mentre ne esiste una in fase di elaborazione, il nuovo aggiornamento viene messo in coda e non verrà eseguito finché tutti gli aggiornamenti precedenti dello schema non saranno stati completati. Per evitare questa situazione, pianifica aggiornamenti di schema più ampi, anziché inviare molti aggiornamenti incrementali dello schema in un breve periodo. Per ulteriori informazioni sugli aggiornamenti dello schema, incluso come eseguire un aggiornamento dello schema che richiede la convalida dei dati, consulta la documentazione sull'aggiornamento dello schema di Spanner

Valuta l'accesso e le dimensioni del database

Quando sviluppi il tuo server di gioco e i tuoi servizi di piattaforma per utilizzare Spanner, considera come il gioco accede al database e come dimensionarlo per evitare costi inutili.

Usa driver e librerie integrati

Quando sviluppi in base a Spanner, considera come il tuo codice si interfaccia con il database. Spanner offre librerie client integrate per molti linguaggi popolari, che in genere sono ricchi di funzionalità e offrono prestazioni elevate. Sono disponibili anche driver JDBC che supportano le istruzioni Data Manipulation Language (DML) e Data Definition Language (DDL). Nei casi in cui Spanner viene utilizzato nel nuovo sviluppo, ti consigliamo di utilizzare le librerie client di Cloud per Spanner. Anche se le integrazioni tipiche dei motori di gioco non offrono molta flessibilità nella selezione della lingua, per i servizi di piattaforma che accedono a Spanner ci sono casi di clienti di giochi che utilizzano Java o Go. Per le applicazioni a velocità effettiva elevata, seleziona una libreria in cui puoi utilizzare lo stesso client Spanner per più richieste sequenziali.

Dimensiona il database in base alle esigenze di test e produzione

Durante lo sviluppo, un'istanza Spanner a nodo singolo è probabilmente sufficiente per la maggior parte delle attività, inclusi i test funzionali.

Valuta le esigenze di Spanner per la produzione

Quando passi dallo sviluppo al test e poi alla produzione, è importante rivalutare l'esigenza di Spanner per garantire che il gioco possa gestire il traffico di giocatori in tempo reale.

Prima di passare alla produzione, i test di carico sono fondamentali per verificare che il backend sia in grado di gestire il carico durante la produzione. Consigliamo di eseguire test di carico con un carico raddoppiato rispetto a quello previsto in produzione, in modo da prepararti a picchi di utilizzo e casi in cui il tuo gioco è più popolare del previsto.

Esegui test di carico utilizzando dati reali

Non è sufficiente eseguire un test di carico con dati sintetici. Dovresti anche eseguire test di carico utilizzando dati e pattern di accesso il più vicino possibile a quanto previsto in produzione. I dati sintetici potrebbero non rilevare potenziali hotspot nella progettazione dello schema Spanner. Non c'è niente di meglio che eseguire un beta test (aperto o chiuso) con giocatori reali per verificare il comportamento di Spanner con i dati reali.

Il seguente diagramma è un esempio di schema di una tabella dei giocatori tratto da uno studio di giochi che illustra l'importanza di utilizzare i beta test per il test di carico.

Elenco dei nomi dei giocatori e un attributo per i test di carico.

Lo studio ha preparato questi dati in base alle tendenze di un gioco precedente operato da un paio di anni. L'azienda si aspettava che lo schema rappresentasse bene i dati del nuovo gioco.

A ogni record di giocatore sono associati alcuni attributi numerici che monitorano i progressi del giocatore nel gioco (come il ranking e il tempo di gioco). Per l'attributo di esempio usato nella tabella precedente, ai nuovi giocatori viene assegnato un valore iniziale di 50, che poi diventa un valore compreso tra 1 e 100 man mano che il giocatore avanza.

Lo studio vuole indicizzare questo attributo per velocizzare le query importanti durante il gameplay.

In base a questi dati, Studio ha creato la seguente tabella di Spanner, con una chiave primaria utilizzando PlayerID e un indice secondario su Attribute.

CREATE TABLE Player (
        PlayerID STRING(36) NOT NULL,
        Attribute INT64 NOT NULL
) PRIMARY KEY (PlayerID)

CREATE INDEX idx_attribute ON Player(Attribute)

È stata eseguita una query sull'indice per trovare fino a dieci giocatori con Attribute=23, come segue:

SELECT PlayerID
        FROM Player@{force_index=idx_attribute}
        WHERE Attribute = 23
        LIMIT 10

Secondo la documentazione sull'ottimizzazione della progettazione dello schema, Spanner archivia i dati di indice allo stesso modo delle tabelle, con una riga per voce di indice. Nei test di carico, questo modello svolge un job accettabile di distribuzione del carico di lettura e scrittura dell'indice secondario su più suddivisioni di Spanner, come illustrato nel seguente diagramma:

Player distribuiti su Spanner suddivisi in base al loro attributo.

Sebbene i dati sintetici utilizzati nel test di carico siano simili allo stato stazionario finale del gioco in cui i valori di Attribute sono ben distribuiti, il design del gioco indica che tutti i giocatori iniziano con Attribute=50. Poiché ogni nuovo giocatore inizia con Attribute=50, quando entrano a far parte di nuovi giocatori, questi vengono inseriti nella stessa parte dell'indice secondario idx_attribute. Ciò significa che gli aggiornamenti vengono instradati alla stessa suddivisione di Spanner, causando un hotspot durante la finestra di lancio del gioco. Si tratta di un uso non efficiente di Spanner.

Giocatori al lancio con lo stesso attributo che creano un hotspot in una singola suddivisione Spanner.

Nel diagramma seguente, l'aggiunta di una colonna IndexPartition allo schema dopo il lancio risolve il problema dell'hotspot e i player vengono distribuiti uniformemente tra le suddivisioni Spanner disponibili. Il comando aggiornato per la creazione della tabella e dell'indice ha il seguente aspetto:

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)

L'aggiunta di una colonna IndexPartition allo schema distribuisce uniformemente i giocatori al momento dell'avvio.

Il valore IndexPartition deve avere un intervallo limitato per eseguire query efficienti, ma deve anche avere un intervallo che sia almeno il doppio del numero di suddivisioni per una distribuzione efficiente.

In questo caso, lo studio ha assegnato manualmente a ogni giocatore un valore IndexPartition tra il giorno 1 e il giorno 6 nell'applicazione di gioco.

Altri metodi potrebbero essere l'assegnazione di un numero casuale a ogni giocatore o l'assegnazione di un valore derivato da un hash sul valore PlayerID. Consulta Cosa devono sapere i database su Spanner, parte 1: chiavi e indici per ulteriori strategie dello sharding a livello di applicazione.

L'aggiornamento della query precedente per utilizzare questo indice migliorato ha il seguente aspetto:

SELECT PlayerID
        FROM Player@{force_index=idx_attribute}
        WHERE IndexPartition BETWEEN 1 and 6
        AND Attribute = 23
        LIMIT 10

Poiché non è stato eseguito alcun beta test, lo studio non si è reso conto che lo stava utilizzando utilizzando dati con ipotesi errate. Sebbene i test di carico sintetico siano un ottimo modo per convalidare il numero di query al secondo (QPS) che l'istanza è in grado di gestire, è necessario un beta test con giocatori reali per convalidare lo schema e preparare un lancio di successo.

Dimensionare l'ambiente di produzione per anticipare il picco della domanda

I giochi principali spesso registrano un picco di traffico al momento del lancio. La creazione di un backend scalabile non si applica solo ai servizi di piattaforma e ai server di gioco dedicati, ma anche ai database. Utilizzando le soluzioni Google Cloud come App Engine, puoi creare servizi API frontend con possibilità di scale up rapidamente. Anche se Spanner offre la flessibilità di aggiungere e rimuovere nodi online, non è un database con scalabilità automatica. Devi eseguire il provisioning di un numero di nodi sufficiente per gestire il picco di traffico al momento del lancio.

In base ai dati raccolti durante il test di carico o da qualsiasi beta test pubblico, puoi stimare il numero di nodi necessari per gestire le richieste al momento del lancio. È buona norma aggiungere alcuni nodi come buffer nel caso in cui dovessero avere più player del previsto. Dovresti sempre dimensionare il database in base a non superare un utilizzo medio della CPU del 65%.

Riscalda il database prima del lancio del gioco

Prima di lanciare il gioco, ti consigliamo di preparare il tuo database per sfruttare le funzionalità di parallelizzazione di Spanner. Per ulteriori informazioni, consulta Riscaldamento del database prima dell'avvio dell'applicazione.

Monitorare e comprendere il rendimento

Qualsiasi database di produzione richiede metriche complete di monitoraggio e prestazioni. Spanner include metriche integrate in Cloud Monitoring. Se possibile, ti consigliamo di incorporare le librerie gRPC fornite nel processo di backend del tuo gioco, poiché queste librerie includono il tracciamento di OpenCensus. Il tracciamento OpenCensus consente di visualizzare le tracce delle query in Cloud Trace e in altri strumenti di tracciamento open source supportati.

In Cloud Monitoring puoi visualizzare i dettagli sull'utilizzo di Spanner, tra cui l'utilizzo dell'archiviazione dei dati e della CPU. Nella maggior parte dei casi, ti consigliamo di basare le decisioni di scalabilità di Spanner su questa metrica di utilizzo della CPU o sulla latenza osservata. Per maggiori informazioni sull'utilizzo suggerito della CPU per prestazioni ottimizzate, consulta le best practice.

Spanner offre piani di esecuzione delle query. Puoi rivedere questi piani nella console Google Cloud e contattare l'assistenza se hai bisogno di aiuto per comprendere le prestazioni delle query.

Quando valuti le prestazioni, mantieni al minimo i test con cicli brevi perché Spanner suddivide in modo trasparente i tuoi dati dietro le quinte per ottimizzare le prestazioni in base ai tuoi pattern di accesso ai dati. Dovresti valutare le prestazioni utilizzando carichi di query realistici e sostenuti.

Quando rimuovi i dati, elimina le righe anziché creare nuovamente le tabelle

Quando lavori con Spanner, per migliorare le prestazioni non è ancora stata eseguita la suddivisione in base al carico o alle dimensioni delle tabelle appena create. Quando elimini i dati eliminando una tabella e poi ricreandola, Spanner ha bisogno di dati, query e tempo per determinare i segmenti corretti per la tua tabella. Se prevedi di ricompilare una tabella con lo stesso tipo di dati (ad esempio, quando esegui test delle prestazioni consecutivi), puoi eseguire una query DELETE sulle righe contenenti i dati non più necessari. Per lo stesso motivo, gli aggiornamenti dello schema devono utilizzare l'API Cloud Spanner fornita e devono evitare una strategia manuale, come la creazione di una nuova tabella e la copia dei dati da un'altra tabella o da un file di backup.

Seleziona una località dei dati per soddisfare i requisiti di conformità

Molti giochi devono rispettare le leggi sulla località dei dati, come il GDPR, quando vengono giocati in tutto il mondo. Per supportare le tue esigenze relative al GDPR, consulta il white paper Google Cloud e il GDPR e seleziona la configurazione regionale di Spanner corretta.

Passaggi successivi