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 è destinato agli ingegneri di backend di giochi che lavorano all'archiviazione dello stato a lungo termine e agli operatori e amministratori dell'infrastruttura di gioco che supportano questi sistemi e sono interessati a ospitare il proprio database di backend suGoogle Cloud.

I giochi multiplayer e online si sono evoluti fino a richiedere strutture di database sempre più complesse per il monitoraggio dei diritti, dello stato e dei dati di inventario dei giocatori. L'aumento del numero di giocatori e la crescente complessità dei giochi hanno portato a soluzioni di database difficili da scalare e gestire, che spesso richiedono l'utilizzo di sharding o clustering. Il monitoraggio di oggetti di valore in-game o dei progressi critici dei giocatori in genere richiede transazioni ed è difficile da aggirare in molti tipi di database distribuiti.

Spanner è il primo servizio di database scalabile di livello enterprise a elevata coerenza distribuito su scala globale, espressamente concepito per il cloud allo scopo di combinare i vantaggi della struttura dei database relazionali con la scalabilità orizzontale non relazionale. Molte aziende di giochi hanno scoperto che è adatto a sostituire sia lo stato del gioco sia i database di autenticazione nei sistemi su scala di produzione. Puoi scalare per ottenere prestazioni o spazio di archiviazione aggiuntivi utilizzando la consoleGoogle Cloud per aggiungere nodi. Spanner può gestire in modo trasparente la replica globale conelevata coerenzaa, eliminando la necessità di gestire le repliche regionali.

Questo documento sulle best practice tratta i seguenti argomenti:

  • Concetti importanti di Spanner e differenze rispetto ai database comunemente utilizzati nei giochi.
  • Quando Spanner è il database giusto per il tuo gioco.
  • Pattern da evitare quando utilizzi Spanner per i giochi.
  • Progettazione delle operazioni di database con Spanner come database del gioco.
  • Modellare i dati e creare uno schema per ottenere le migliori prestazioni con Spanner.

Terminologia

Diritti
Giochi, espansioni o acquisti in-app appartenenti a un giocatore.
Informazioni che consentono l'identificazione personale (PII)
Nei giochi, informazioni che in genere includono indirizzo email e dati dell'account di pagamento, come numero di carta di credito e indirizzo di fatturazione. In alcuni mercati, queste informazioni potrebbero includere un numero di documento di identità nazionale.
Database di gioco
Un database che contiene i progressi e l'inventario di un giocatore per un gioco.
Database di autenticazione (auth DB)
Un database che include i diritti dei giocatori e i PII che i giocatori utilizzano quando effettuano un acquisto. Il database di autenticazione è noto anche come database dell'account o database dei giocatori. Questo database a volte viene combinato con il database dei giochi, ma spesso sono separati negli studi o negli editori che hanno più titoli.
Transazione
Una transazione di database: un insieme di operazioni di scrittura che hanno un effetto tutto o niente. La transazione ha esito positivo e tutti gli aggiornamenti vengono applicati oppure il database viene riportato a uno stato che non include nessuno degli aggiornamenti della transazione. Nei giochi, le transazioni di database sono fondamentali durante l'elaborazione dei pagamenti e l'assegnazione della proprietà di inventario o valuta di gioco 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. Questi vengono utilizzati di frequente perché possono fornire metodologie familiari e garanzie solide per le transazioni.
Database NoSQL (NoSQL DB)
Database non strutturati in modo relazionale. Questi database stanno diventando sempre più popolari nei giochi perché offrono molta flessibilità quando il modello dei dati cambia. I database NoSQL includono MongoDB e Cassandra.
Chiave primaria
In genere, la colonna che contiene l'ID univoco per gli articoli di inventario, gli account giocatore e le transazioni di acquisto.
Istanza
Un unico database. Ad esempio, un cluster esegue più copie del software di database, ma appare come una singola istanza al backend del gioco.
Nodo
Ai fini di questo documento, una singola macchina che esegue una copia del software del database.
Replica
Una seconda copia di un database. Le repliche vengono spesso utilizzate per il recupero dei dati e l'alta disponibilità oppure per aumentare il throughput di lettura.
Cluster
Più copie del software in esecuzione su più computer che insieme appaiono come una singola istanza per il backend del gioco. Il clustering viene utilizzato per la scalabilità e la disponibilità.
Shard
Un'istanza di un database. Molti studi di sviluppo di giochi eseguono più istanze di database omogenee, ognuna delle quali contiene un sottoinsieme dei dati del gioco. Ciascuna di queste istanze è comunemente chiamata shard. Lo sharding viene in genere eseguito per migliorare le prestazioni o la scalabilità, sacrificando l'efficienza di gestione e aumentando la complessità dell'app. Lo sharding in Spanner viene implementato utilizzando le divisioni.
Suddividi
Spanner divide i dati in blocchi chiamati split, dove i singoli split possono spostarsi indipendentemente l'uno dall'altro e venire assegnati a server diversi. Una suddivisione è definita come un intervallo di righe in una tabella di primo livello (ovvero non interleaved), 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, il che modifica il numero di suddivisioni nel database. Spanner divide i dati in base al carico: aggiunge automaticamente i confini della suddivisione quando rileva un carico di lettura o scrittura elevato distribuito tra molte chiavi in una suddivisione.
Hotspot
Quando una singola suddivisione in un database distribuito come Spanner contiene record che ricevono una parte significativa di tutte le query inviate al database. Questo scenario non è auspicabile perché peggiora il rendimento.

Utilizzo di Spanner per i giochi

Nella maggior parte dei casi in cui stai prendendo in considerazione un RDBMS per il tuo gioco, Spanner è una scelta appropriata perché può sostituire efficacemente il DB di gioco, il DB di autenticazione o, in molti casi, entrambi.

DB di gioco

Spanner può operare come singola autorità transazionale 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 a un altro rappresenta una sfida nei backend di 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 dei giocatori e la quantità di dati archiviati. Ciò spesso porta gli sviluppatori di giochi a partizionare il database per ottenere prestazioni aggiuntive o a memorizzare tabelle in continua crescita. Questo tipo di soluzione comporta complessità operative e un elevato overhead di manutenzione.

Per contribuire a ridurre questa complessità, una strategia comune consiste nell'eseguire regioni di gioco completamente separate senza possibilità di spostare i dati tra di loro. In questo caso, gli articoli e la valuta non possono essere scambiati tra giocatori di regioni di gioco diverse, perché gli inventari di ogni regione sono separati in database distinti. Tuttavia, questa configurazione sacrifica l'esperienza di gioco preferita a favore della semplicità operativa e per gli sviluppatori.

D'altra parte, puoi consentire le transazioni tra regioni in un database con partizionamento geografico, ma spesso a un costo di complessità elevato. Questa configurazione richiede che le transazioni si estendano su più istanze di database, il che comporta una logica complessa e soggetta a errori lato applicazione. Il tentativo di ottenere blocchi delle transazioni su più database può avere un impatto significativo sulle prestazioni. Inoltre, l'impossibilità di fare affidamento su transazioni atomiche può portare a exploit dei giocatori, come la duplicazione di valuta o oggetti di gioco, che danneggiano l'ecosistema e la community del gioco.

Spanner può semplificare il tuo approccio alle transazioni di inventario e valuta. Anche quando utilizzi Spanner per archiviare tutti i dati del gioco in tutto il mondo, offre transazioni di lettura/scrittura con proprietà ACID (atomicità, coerenza, isolamento e durabilità) ancora più solide di quelle convenzionali. Grazie alla scalabilità di Spanner, i dati non devono essere suddivisi in istanze di database separate quando sono necessarie prestazioni o spazio di archiviazione maggiori. Al contrario, puoi aggiungere altri nodi. Inoltre, l'alta disponibilità e la resilienza dei dati per cui i giochi spesso raggruppano i propri database vengono gestite in modo trasparente da Spanner, senza richiedere configurazione o gestione aggiuntiva.

Auth DBs

I database di autenticazione possono essere gestiti bene anche da Spanner, soprattutto se vuoi standardizzare un singolo RDBMS a livello di studio o editore. 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 renderlo interessante. 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"), con "cinque nove" che 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 giocatore.

Best practice

Questa sezione fornisce consigli su come utilizzare Spanner nella progettazione di giochi. È importante modellare i dati di gioco per usufruire delle funzionalità uniche offerte da Spanner. Sebbene tu possa accedere a Spanner utilizzando la semantica dei database relazionali, alcuni punti di progettazione dello schema possono aiutarti a migliorare il rendimento. La documentazione di Spanner contiene consigli dettagliati per la progettazione dello schema che puoi consultare, ma le sezioni seguenti contengono alcune best practice per i database di giochi.

Le pratiche descritte in questo documento si basano sulle esperienze di utilizzo e sui casi di studio dei clienti.

Utilizzare gli UUID come ID giocatore e personaggio

La tabella dei giocatori in genere ha una riga per ogni giocatore e la sua valuta in-game, i suoi progressi o altri dati che non vengono mappati facilmente nelle righe della tabella dell'inventario discreto. Se il tuo gioco consente ai giocatori di avere progressi salvati separati per più personaggi, come molti grandi giochi multiplayer di massa persistenti, questa tabella in genere contiene una riga per ogni personaggio. Il pattern è altrimenti lo stesso.

Ti consigliamo di utilizzare un identificatore di personaggio o giocatore univoco a livello globale (ID personaggio) come chiave primaria della tabella dei personaggi. Ti consigliamo inoltre di utilizzare l'UUID (Universally Unique Identifier) v4, perché distribuisce i dati dei giocatori tra i nodi del database e può aiutarti a ottenere prestazioni migliori da Spanner.

Utilizzare l'interleaving per le tabelle dell'inventario

La tabella dell'inventario spesso contiene elementi di gioco, come l'equipaggiamento del personaggio, carte o unità. In genere, un singolo giocatore ha molti articoli nel suo inventario. Ogni elemento è rappresentato da una singola riga nella tabella.

Analogamente ad altri database relazionali, una tabella dell'inventario in Spanner ha una chiave primaria che è un identificatore univoco a livello globale per l'articolo, 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, itemID e playerID sono troncati per migliorarne la leggibilità. Una tabella dell'inventario reale conterrebbe anche molte altre colonne che non sono incluse nell'esempio.

Un approccio tipico in un RDBMS per il monitoraggio della proprietà degli elementi è l'utilizzo di una colonna come chiave esterna che contiene l'ID giocatore del proprietario attuale. 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 dei giocatori associata per migliorare le prestazioni. Quando utilizzi tabelle interleaved, tieni presente quanto segue:

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

Progettare l'indicizzazione per evitare gli hotspot

Molti sviluppatori di giochi implementano indici su molti campi dell'inventario per ottimizzare determinate query. In Spanner, la creazione o l'aggiornamento di una riga con dati in questo indice 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.

Nel seguente esempio, è presente una tabella per i record dei punteggi più alti 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, uno stage o una stagione e il punteggio del giocatore.

Per velocizzare le query che filtrano in base alla modalità di gioco, considera il seguente indice:

CREATE INDEX idx_score_ranking ON Ranking (
        GameMode,
        Score DESC
)

Se tutti giocano alla stessa modalità di gioco chiamata 1, questo indice crea un hotspot in cui GameMode=1. Se vuoi ottenere una classifica per questa modalità di gioco, l'indice scansiona solo le righe contenenti GameMode=1, restituendo rapidamente la classifica.

Se modifichi l'ordine dell'indice precedente, puoi risolvere questo problema dell'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, ottenere i punteggi non sarà veloce come con l'indice precedente perché la query esamina tutti i punteggi di tutte le modalità per determinare se GameMode=1.

Di conseguenza, l'indice riordinato risolve il problema precedente della modalità Gioco, ma ha ancora margini di miglioramento, come illustrato nel seguente design.

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

CREATE INDEX idx_score_ranking ON Ranking (
        Score DESC
)

Ti consigliamo di spostare la modalità di gioco fuori dallo schema della tabella e di utilizzare una tabella per modalità, se possibile. Utilizzando questo metodo, quando recuperi i punteggi per una modalità, esegui query solo su una tabella contenente i punteggi per quella modalità. Questa tabella può essere indicizzata in base al punteggio per recuperare rapidamente gli intervalli di punteggio senza un 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 numero più che sufficiente per la maggior parte dei giochi.

Database separati per tenant

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

Evita aggiornamenti incrementali dello schema

A differenza di alcuni database relazionali convenzionali, Spanner rimane operativo durante gli aggiornamenti dello schema. Vengono restituite tutte le query sullo schema precedente (anche se potrebbero essere restituite più lentamente del solito) e le query sul nuovo schema vengono restituite man mano che diventano disponibili. Puoi progettare la procedura di aggiornamento in modo da mantenere il gioco in esecuzione durante gli aggiornamenti dello schema quando viene eseguito su Spanner, a condizione che tu tenga presente i vincoli precedenti.

Tuttavia, se richiedi un'altra modifica dello schema mentre ne è in corso una, il nuovo aggiornamento viene messo in coda e non avrà luogo finché tutti gli aggiornamenti dello schema precedenti non saranno completati. Puoi evitare questa situazione pianificando aggiornamenti dello schema più grandi, anziché eseguire 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.

Considera l'accesso e le dimensioni del database

Quando sviluppi i servizi di server di gioco e piattaforma per utilizzare Spanner, valuta in che modo il gioco accede al database e come dimensionare il database per evitare costi inutili.

Utilizzare driver e librerie integrati

Quando sviluppi in base a Spanner, considera il modo in cui il codice interagisce con il database. Spanner offre librerie client integrate per molti linguaggi popolari, che in genere sono ricche di funzionalità e performanti. Sono disponibili anche driver JDBC, che supportano istruzioni di data manipulation language (DML) e Data Definition Language (DDL). Nei casi in cui Spanner viene utilizzato in un nuovo sviluppo, ti consigliamo di utilizzare le librerie client Cloud per Spanner. Sebbene le integrazioni tipiche dei motori di gioco non offrano 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 ad alto rendimento, 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 un solo nodo è probabilmente sufficiente per la maggior parte delle attività, inclusi i test funzionali.

Valuta le esigenze di Spanner per la produzione

Quando passi dallo sviluppo ai test e poi alla produzione, è importante rivalutare le tue esigenze di Spanner per assicurarti che il tuo gioco possa gestire il traffico dei giocatori in tempo reale.

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

Eseguire test di carico utilizzando dati reali

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

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

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

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

Ogni record del giocatore ha alcuni attributi numerici associati che monitorano i progressi del giocatore nel gioco (ad esempio, il grado e il tempo di gioco). Per l'attributo di esempio utilizzato nella tabella precedente, ai nuovi giocatori viene assegnato un valore iniziale di 50, che poi cambia in 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.

Sulla base di questi dati, lo studio ha creato la seguente tabella Spanner, con una chiave primaria che utilizza 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 10 giocatori con Attribute=23, in questo modo:

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

Secondo la documentazione sull'ottimizzazione della progettazione dello schema, Spanner memorizza i dati dell'indice nello stesso modo delle tabelle, con una riga per ogni voce dell'indice. Nei test di carico, questo modello distribuisce in modo accettabile il carico di lettura e scrittura dell'indice secondario su più suddivisioni di Spanner, come illustrato nel seguente diagramma:

Giocatori distribuiti tra le suddivisioni di Spanner 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, la progettazione del gioco prevede che tutti i giocatori inizino con Attribute=50. Poiché ogni nuovo giocatore inizia con Attribute=50, quando nuovi giocatori si uniscono vengono inseriti nella stessa parte dell'indice secondario idx_attribute. Ciò significa che gli aggiornamenti vengono indirizzati alla stessa suddivisione di Spanner, causando un hotspot durante la finestra di lancio del gioco. Questo è un utilizzo inefficiente di Spanner.

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

Nel seguente diagramma, l'aggiunta di una colonna IndexPartition allo schema dopo il lancio risolve il problema dell'hotspot e i giocatori vengono distribuiti uniformemente tra le divisioni Spanner disponibili. Il comando aggiornato per creare la tabella e l'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 all'avvio.

Il valore di IndexPartition deve avere un intervallo limitato per una query efficiente, ma deve anche avere un intervallo almeno doppio rispetto al numero di suddivisioni per una distribuzione efficiente.

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

Metodi alternativi 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 l'articolo What DBAs need to know about Spanner, part 1: Keys and indexes per altre strategie di partizionamento a livello di applicazione.

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

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

Poiché non è stato eseguito alcun test beta, lo studio non si è reso conto di eseguire test utilizzando dati con ipotesi errate. Sebbene i test di carico sintetici siano un buon modo per convalidare il numero di query al secondo (QPS) che la tua istanza può gestire, è necessario un test beta con giocatori reali per convalidare lo schema e preparare un lancio riuscito.

Dimensiona l'ambiente di produzione per anticipare il picco di domanda

I giochi più importanti spesso raggiungono il picco di traffico al lancio. La creazione di un backend scalabile si applica non solo ai servizi della piattaforma e ai server di gioco dedicati, ma anche ai database. Utilizzando soluzioni come App Engine, puoi creare servizi API di frontend scalabili rapidamente. Google Cloud 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 sufficiente di nodi per gestire il picco di traffico al lancio.

In base ai dati raccolti durante il test di carico o da qualsiasi test beta 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 si verifichino più giocatori del previsto. Devi sempre dimensionare il database in modo da non superare un utilizzo medio della CPU del 65%.

Riscaldare il database prima del lancio del gioco

Prima di lanciare il gioco, ti consigliamo di preparare il database per sfruttare i vantaggi delle funzionalità di parallelizzazione di Spanner. Per saperne di più, consulta Riscaldamento del database prima del lancio 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. Ove possibile, ti consigliamo di incorporare le librerie gRPC fornite nel processo di backend del gioco perché includono la tracciabilità 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, inclusi l'archiviazione dei dati e l'utilizzo 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 ulteriori informazioni sull'utilizzo della CPU consigliato per prestazioni ottimizzate, consulta Best practice.

Spanner offre piani di esecuzione delle query. Puoi esaminare 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, riduci al minimo i test a ciclo breve perché Spanner suddivide in modo trasparente i dati in background per ottimizzare le prestazioni in base ai pattern di accesso ai dati. Devi valutare le prestazioni utilizzando carichi di query realistici e sostenuti.

Quando rimuovi i dati, elimina le righe anziché ricreare le tabelle

Quando lavori con Spanner, le tabelle appena create non hanno ancora avuto l'opportunità di essere suddivise in base al carico o alle dimensioni per migliorare le prestazioni. Quando elimini i dati eliminando una tabella e poi ricreandola, Spanner ha bisogno di dati, query e tempo per determinare le suddivisioni corrette per la tabella. Se prevedi di ripopolare una tabella con lo stesso tipo di dati (ad esempio, quando esegui test delle prestazioni consecutivi), puoi in alternativa eseguire una query DELETE sulle righe contenenti i dati che non ti servono più. Per lo stesso motivo, gli aggiornamenti dello schema devono utilizzare l'API Cloud Spanner fornita ed 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 soddisfare le tue esigenze relative al GDPR, consulta Google Cloud e il white paper sul GDPR e seleziona la configurazione regionale di Spanner corretta.

Passaggi successivi