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 agli sviluppatori di backend di giochi che si occupano di archiviazione dello stato a lungo termine, nonché agli operatori e agli amministratori dell'infrastruttura di giochi 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 monitorare i diritti, lo stato e i dati di inventario dei giocatori. La crescita della base di giocatori e l'aumento della 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 in-game di valore o dell'avanzamento critico del giocatore in genere richiede transazioni ed è difficile aggirare il problema 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 lo hanno trovato adatto a sostituire sia i database di stato del gioco sia quelli di autenticazione nei sistemi di produzione. Puoi eseguire il ridimensionamento per ottenere prestazioni o spazio di archiviazione aggiuntivi utilizzando la consoleGoogle Cloud per aggiungere nodi. Spanner può gestire in modo trasparente la replica globale con elevata coerenza, eliminando la necessità di gestire le repliche regionali.

Questo documento sulle best practice illustra quanto segue:

  • 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 si utilizza Spanner per i giochi.
  • Progettare le operazioni di database con Spanner come database del gioco.
  • Modellazione dei dati e creazione di uno schema per ottenere le migliori prestazioni con Spanner.

Terminologia

Diritti
Giochi, espansioni o acquisti in-app di un giocatore.
Informazioni che consentono l'identificazione personale (PII)
Nei giochi, informazioni che in genere includono indirizzo email e dati dell'account di pagamento, ad esempio un numero di carta di credito e l'indirizzo di fatturazione. In alcuni mercati, queste informazioni potrebbero includere un numero di documento di identità nazionale.
Database di giochi (DB di giochi)
Un database che contiene i progressi e l'inventario del giocatore per un gioco.
Database di autenticazione (auth DB)
Un database che include i diritti dei giocatori e le PII che i giocatori utilizzano per effettuare un acquisto. Il DB auth è noto anche come DB account o DB player. A volte questo database viene combinato con il database di giochi, ma spesso sono separati in case di produzione o publisher con più titoli.
Transazione
Una transazione di database: un insieme di operazioni di scrittura che hanno un effetto tutto o niente. La transazione riesce 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 più importanti durante l'elaborazione dei pagamenti e l'assegnazione della proprietà di inventario o valuta 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. Questi modelli vengono utilizzati di frequente perché possono fornire metodiche familiari e garanzie solide sulle transazioni.
Database NoSQL (DB NoSQL)
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 dei giocatori e le transazioni di acquisto.
Istanza
Un singolo database. Ad esempio, un cluster esegue più copie del software del database, ma viene visualizzato come una singola istanza per il backend del gioco.
Nodo
Ai fini di questo documento, una singola macchina su cui è in esecuzione una copia del software del database.
Replica
Una seconda copia di un database. Le repliche vengono utilizzate di frequente per il recupero dei dati e l'alta disponibilità o per contribuire ad aumentare la velocità effettiva di lettura.
Cluster
Più copie del software in esecuzione su molti computer che insieme appaiono come un'unica 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 gestiscono più istanze di database omogenee, ciascuna delle quali contiene un sottoinsieme dei dati del gioco. Ognuna di queste istanze è comunemente indicata come shard. Lo sharding viene solitamente eseguito per migliorare le prestazioni o la scalabilità, sacrificando l'efficienza della gestione e aumentando al contempo la complessità dell'app. Lo sharding in Spanner viene implementato utilizzando le suddivisioni.
Suddividi
Spanner suddivide i dati in blocchi chiamati split, in cui i singoli split possono spostarsi indipendentemente l'uno dall'altro e essere assegnati a server diversi. Una suddivisione è definita come un intervallo di righe in una tabella di primo livello (in altre parole, non interlacciata), in cui le righe sono ordinate in base alla chiave primaria. Le chiavi iniziale e finale di questo intervallo sono chiamate "confini della suddivisione". Spanner aggiunge e rimuove automaticamente i confini della suddivisione, modificando il numero di suddivisioni nel database. Spanner suddivide i dati in base al carico: aggiunge automaticamente i confini della suddivisione quando rileva un carico elevato di lettura o scrittura distribuito 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 è auspicabile perché riduce il rendimento.

Utilizzo di Spanner per i giochi

Nella maggior parte dei casi in cui stai valutando 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 giochi

Spanner può operare come un'unica autorità transazionale mondiale, il che lo rende ideale per i sistemi di inventario dei giochi. Qualsiasi moneta o articolo in-game che può essere scambiato, venduto, regalato o trasferito in altro modo da un giocatore all'altro rappresenta una sfida per i 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 un solo nodo. 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. Spesso, gli sviluppatori di giochi scelgono di suddividere il database per migliorare le prestazioni o per archiviare tabelle in continua crescita. Questo tipo di soluzione comporta complessità operativa e un elevato overhead di manutenzione.

Per contribuire ad attenuare questa complessità, una strategia comune è eseguire regioni di gioco completamente separate senza alcun modo per spostare i dati da una all'altra. In questo caso, gli oggetti e la valuta non possono essere scambiati tra giocatori di regioni di gioco diverse, perché gli inventari di ogni regione sono suddivisi in database distinti. Tuttavia, questa configurazione sacrifica l'esperienza di riproduzione preferita a favore della semplicità operativa e per gli sviluppatori.

D'altra parte, puoi consentire scambi tra regioni in un database suddiviso in parti geograficamente, ma spesso a un costo elevato in termini di complessità. Questa configurazione richiede che le transazioni si estendano a più istanze di database, il che comporta una logica lato applicazione complessa e soggetta a errori. Il tentativo di ottenere blocchi delle transazioni su più database può avere un impatto significativo sulle prestazioni. Inoltre, non poter fare affidamento su transazioni atomiche può portare a comportamenti illeciti da parte dei giocatori, come la duplicazione di valuta o articoli in-game, che danneggiano l'ecosistema e la community del gioco.

Spanner può semplificare il tuo approccio alle transazioni di inventario e valuta. Anche se utilizzi Spanner per archiviare tutti i dati dei tuoi giochi in tutto il mondo, offre transazioni di lettura/scrittura con proprietà ancora più forti rispetto alle tradizionali atomicità, coerenza, isolamento e durabilità (ACID). Grazie alla scalabilità di Spanner, i dati non devono essere suddivisi in istanze di database separate quando è necessario un maggiore rendimento o spazio di archiviazione. Puoi invece aggiungere altri nodi. Inoltre, l'alta disponibilità e la resilienza dei dati per cui i giochi spesso raggruppano i loro database vengono gestite in modo trasparente da Spanner, senza richiedere alcuna configurazione o gestione aggiuntiva.

DB di autenticazione

Anche i database di autenticazione possono essere gestiti bene da Spanner, soprattutto se vuoi standardizzare un singolo RDBMS a livello di studio o 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 renderlo interessante. La replica dei dati in Spanner è trasparente, sincrona e integrata. Spanner offre configurazioni che offrono 99,99% ("quattro nove") o 99,999% ("cinque nove") di disponibilità, con "cinque nove" che corrispondono a meno di cinque minuti e mezzo di mancata disponibilità 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 consigli su come utilizzare Spanner nel design dei 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 ad aumentare il rendimento. La documentazione di Spanner contiene consigli dettagliati per la progettazione dello schema che puoi esaminare, ma le sezioni seguenti sono alcune best practice per i DB di giochi.

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

Utilizzare gli UUID come ID giocatore e personaggio

La tabella dei giocatori in genere contiene una riga per ogni giocatore e la relativa valuta in-game, il progresso o altri dati che non possono essere facilmente mappati alle righe della tabella dell'inventario discreto. Se il tuo gioco consente ai giocatori di avere salvataggi separati per più personaggi, come molti giochi di massa multiplayer persistenti di grandi dimensioni, questa tabella in genere contiene una riga per ogni personaggio. Il pattern rimane invariato.

Ti consigliamo di utilizzare un identificatore di personaggi o giocatori univoco a livello globale (characterID) come chiave primaria della tabella dei personaggi. Ti consigliamo inoltre di utilizzare il UUID (Universally Unique Identifier) v4, poiché distribuisce i dati dei giocatori tra i nodi del DB e può aiutarti a ottenere un aumento delle prestazioni di Spanner.

Utilizzare l'interlacciamento per le tabelle di inventario

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

Come in altri database relazionali, una tabella di 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 di inventario di esempio, itemID e playerID sono troncati per migliorare la leggibilità. Una tabella di inventario effettiva conterrebbe anche molte altre colonne che non sono incluse nell'esempio.

Un approccio tipico in un RDBMS per monitorare la proprietà degli elementi consiste nell'utilizzare una colonna come chiave esterna che contiene l'ID giocatore dell'attuale proprietario. Questa colonna è la chiave primaria di una tabella di database separata. In Spanner puoi utilizzare il separazione in file, che memorizza le righe di inventario vicino alla riga della tabella dei giocatori associata per migliorare le prestazioni. Quando utilizzi tabelle interlacciate, tieni presente quanto segue:

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

Progetta l'indicizzazione per evitare gli hotspot

Molti sviluppatori di giochi implementano indici su molti dei campi dell'inventario per ottimizzare determinate query. In Spanner, la creazione o l'aggiornamento di una riga con i dati nell'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 implementandoli in altri modi che non influiscono sulle prestazioni del database.

Nel seguente esempio è presente una tabella per i record dei migliori punteggi dei giocatori nel lungo periodo:

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, una fase o una stagione e il punteggio del giocatore.

Per velocizzare le query che filtrano in base alla modalità di gioco, valuta 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 dove GameMode=1. Se vuoi ottenere un ranking per questa modalità di gioco, l'indice esamina solo le righe contenenti GameMode=1, restituendo rapidamente il ranking.

Se modifichi 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 gareggiano nella stessa modalità di gioco, a condizione che i loro punteggi siano distribuiti nell'intervallo possibile. Tuttavia, l'ottenimento dei punteggi non sarà così veloce come con l'indice precedente perché la query analizza tutti i punteggi di tutte le modalità per determinare se GameMode=1.

Di conseguenza, l'indice riordinato risolve l'hotspot precedente nella modalità di 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 dallo schema della tabella e di utilizzare una tabella per modalità, se possibile. Se utilizzi questo metodo, quando recuperi i punteggi per una modalità, esegui una query solo su una tabella contenente i punteggi per quella modalità. Questa tabella può essere indicizzata in base al punteggio per un recupero rapido degli intervalli di punteggi senza un rischio 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, 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 multitenancy in Spanner utilizzando valori di chiave primaria diversi, per i dati di gioco consigliamo l'approccio più convenzionale dei database separati per tenant. Le modifiche allo schema sono comuni con il rilascio di nuove funzionalità di gioco nei giochi con servizio dal vivo e l'isolamento degli 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, poiché queste operazioni vengono eseguite contemporaneamente su un intero database.

Evita gli aggiornamenti incrementali dello schema

A differenza di alcuni database relazionali convenzionali, Spanner rimane operativo durante gli aggiornamenti dello schema. Tutte le query relative al vecchio schema vengono restituite (anche se potrebbero essere restituite più lentamente del solito) e le query relative al nuovo schema vengono restituite man mano che diventano disponibili. Puoi progettare la procedura di aggiornamento in modo da mantenere in esecuzione il gioco 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 verrà eseguito finché non saranno stati completati tutti gli aggiornamenti dello schema precedenti. Puoi evitare questa situazione pianificando aggiornamenti dello schema più grandi, anziché emettere molti aggiornamenti incrementali dello schema in un breve periodo di tempo. Per ulteriori informazioni sugli aggiornamenti dello schema, inclusa la procedura per 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 il server di gioco e i servizi della piattaforma per l'utilizzo di Spanner, valuta in che modo il gioco accede al database e come impostarne le dimensioni per evitare costi non necessari.

Utilizzare driver e librerie integrati

Quando sviluppi per Spanner, tieni conto di come il codice interagisce con il database. Spanner offre librerie client integrate per molti linguaggi comuni, che in genere sono ricchi di funzionalità e performanti. Sono disponibili anche driver JDBC che supportano le istruzioni DML (Data Manipulation Language) e DDL (Data Definition Language). Nei casi in cui Spanner viene utilizzato per nuovi sviluppi, consigliamo di utilizzare le librerie client di Cloud per Spanner. Sebbene le integrazioni dei motori di gioco tipici non offrano molta flessibilità nella scelta del linguaggio, per i servizi della piattaforma che accedono a Spanner esistono casi di clienti di giochi che utilizzano Java o Go. Per le applicazioni con un elevato throughput, 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, è probabile che un'istanza Spanner a un solo nodo sia sufficiente per la maggior parte delle attività, inclusi i test funzionali.

Valutare 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 tuo backend possa gestire il carico durante la produzione. Ti consigliamo di eseguire test di carico con il doppio del carico previsto in produzione per prepararti agli picchi di utilizzo e ai casi in cui il tuo gioco è più popolare del previsto.

Esegui test di carico utilizzando dati reali

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

Il seguente diagramma è uno schema di esempio della tabella dei giocatori di uno studio di giochi che illustra l'importanza dell'utilizzo dei beta test per i 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 che aveva gestito per un paio di anni. L'azienda si aspettava che lo schema rappresentasse bene i dati di questo nuovo gioco.

A ogni record del giocatore sono associati alcuni attributi numerici che monitorano i progressi del giocatore nel gioco (ad esempio il ranking 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 diventa 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, 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 dieci giocatori con Attribute=23, come mostrato di seguito:

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

In base alla documentazione sull'ottimizzazione della progettazione dello schema, Spanner immagazzina i dati dell'indice nello stesso modo delle tabelle, con una riga per 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 all'eventuale stato stabile del gioco in cui i valori Attribute sono ben distribuiti, il design del gioco prevede che tutti i giocatori inizino con Attribute=50. Poiché ogni nuovo giocatore inizia con Attribute=50, quando si uniscono nuovi giocatori, vengono inseriti nella stessa parte dell'indice secondario idx_attribute. Ciò significa che gli aggiornamenti vengono indirizzati alla stessa suddivisione Spanner, causando un hotspot durante la finestra di lancio del gioco. Si tratta di un utilizzo inefficiente di Spanner.

I giocatori al momento del 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 suddivisioni di Spanner disponibili. Il comando aggiornato per la creazione della tabella e dell'indice è il seguente:

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 del lancio.

Il valore IndexPartition deve avere un intervallo limitato per query efficienti, 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 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 Informazioni che i DBA devono conoscere su Spanner, parte 1: chiavi e indici per scoprire di più sulle strategie di sharding 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 beta test, lo studio non si è reso conto di eseguire il test utilizzando dati con presupposti errati. 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 beta test con giocatori reali per convalidare il tuo schema e preparare un lancio efficace.

Dimensiona l'ambiente di produzione in modo da anticipare i picchi di domanda

I giochi più importanti spesso registrano il picco di traffico al momento del 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 Google Cloud come App Engine, puoi creare servizi API frontend che possono essere scalati 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 sufficiente di nodi per gestire il picco di traffico al momento del lancio.

In base ai dati raccolti durante i 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 tu riceva più giocatori del previsto. Devi sempre determinare le dimensioni del database in base al non superare un utilizzo medio della CPU del 65%.

Esegui l'inizializzazione del database prima del lancio del gioco

Prima di lanciare il gioco, ti consigliamo di preriscaldare il database per sfruttare le funzionalità di parallelizzazione di Spanner. Per ulteriori informazioni, consulta Eseguire l'inizializzazione 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 tuo gioco perché includono il monitoraggio OpenCensus. Il monitoraggio OpenCensus ti consente di visualizzare le tracce delle query in Cloud Trace, nonché altri strumenti di monitoraggio open source supportati.

In Monitoraggio di Cloud puoi visualizzare i dettagli sull'utilizzo di Spanner, tra cui lo spazio di 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 suggerito della CPU per prestazioni ottimizzate, consulta le 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 il rendimento delle query.

Quando valuti le prestazioni, riduci al minimo i test a ciclo breve perché Spanner suddivide in modo trasparente i dati dietro le quinte per ottimizzare le prestazioni in base ai pattern di accesso ai dati. Devi valutare il rendimento utilizzando carichi di query realistici e duraturi.

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

Quando utilizzi Spanner, le tabelle appena create non hanno ancora avuto la possibilità di essere suddivise in base al carico o alle dimensioni per migliorare le prestazioni. Quando elimini i dati eliminando una tabella e poi la ricrei, Spanner ha bisogno di dati, query e tempo per determinare le suddivisioni corretta per la tabella. Se prevedi di rieseguire il popolamento di una tabella con lo stesso tipo di dati (ad esempio quando esegui test di rendimento consecutivi), puoi 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 il documento Google Cloud e il white paper sul GDPR e seleziona la configurazione regionale di Spanner corretta.

Passaggi successivi