Qual è la migliore architettura server per i giochi in tempo reale?


10

Sto sviluppando un gioco in tempo reale che dovrebbe contenere migliaia di giocatori in tempo reale (tipo FPS. Ritardo massimo di 1 secondo). Quale sarebbe la migliore infrastruttura per questo?

La mia idea era quella di utilizzare 2 cluster di server, uno per il Server End (tutto il lato informatico) e uno per il Database, in cui un bilanciamento del carico è "responsabile" per ciascuno dei cluster. Un server principale riceverà le richieste dagli utenti e rinvierà l'indirizzo IP del server pertinente affinché l'utente possa gestirlo.

Il cluster di database utilizzerà la replica del database per coerenza tra i database.

Dovrebbe esserci anche un bilanciamento del carico geografico, quindi assegnerà il bilanciamento del carico regionale a ciascun utente per la migliore risposta.

Sto usando .NET + MSSQL per il gioco.

Grazie!


2
Quando dici "infrastruttura", intendi software, hardware, servizi o volevi solo che criticavamo il tuo piano esistente così com'è?
Tetrad

1
@Nate - stiamo pianificando di ridimensionare, non duplicare - quindi dovrebbe essere completamente scalabile.
romano,

2
-1 perché teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html - Non copri alcun requisito di capacità, dici che il gioco non è frammentato ma è suddiviso in zone , ecc. La natura delle ottimizzazioni delle prestazioni, inclusa la scalabilità, richiede informazioni specifiche e non esiste un'architettura ottimale in assoluto.

1
Vorrei riformulare la tua domanda con qualcosa di più concreto. Qual è il "migliore", in modo fattuale e non soggettivo? Intendi il più facile da ridimensionare, il più facile da gestire, il più facile da avviare, il più veloce o cosa?
Il comunista Duck il

1
"Più semplice" è anche soggettivo. Più facile per chi, in quale arco di tempo, quali risorse? Stack Exchanges funziona meglio con domande specifiche: "Ho creato questo server usando LINQ e MSSQL, ma è caduto dopo 70 transazioni / secondo, ecco le mie prime due transazioni che rappresentano il 73% del mio tempo di esecuzione, come devo aumentare il mio rendimento? "

Risposte:


6

Non esiste architettura migliore senza sapere molto di più sulle vostre esigenze, ad es. il tipo di interazioni tra i personaggi, la quantità di dati che saranno persistenti e così via.

Se riesci a far fronte a 1 secondo di latenza, puoi probabilmente ospitare 1000 giocatori su un singolo server senza problemi, ma questo è in realtà in conflitto con l'idea di un FPS poiché in genere richiedono una latenza molto più bassa, ad es. meno di 100 ms. Ma un sistema in grado di gestire un'elevata latenza può permettersi di fare tutto tramite il passaggio di messaggi, il che rende la consistenza piuttosto banale. Fornire la tua logica è abbastanza semplice, cioè - la logica complessa peggiora anche quando la trasformi in un sistema basato su messaggi piuttosto che in un sistema a oggetti bloccati - ma tutto dipende dalle esigenze della tua applicazione.

Allo stesso modo, se non si persistono molti dati, non è necessario il computer del database, ma senza saperlo, è difficile dirlo. Se stai persistendo piccole quantità di dati, e forse lo fai solo alla fine di un torneo o qualcosa del genere, di nuovo non hai bisogno di un database separato, certamente non un cluster di essi. D'altra parte se non stai persistendo molto ma stai leggendo molto, è qui che i database replicati possono aiutarti - ma indica anche che un database relazionale potrebbe non essere la migliore corrispondenza per il tuo problema in primo luogo. Spesso una cache in memoria è una soluzione migliore. Allo stesso modo, se non ci sono interazioni in stile transazione tra i personaggi, la coerenza diventa meno importante. (E se ci sono solo alcune di queste transazioni, puoi renderle un caso speciale.)

In effetti, diffidare dall'adozione di un RDBMS solo perché è la cosa fatta in sistemi di grandi dimensioni. Anche se personalmente approvo il loro utilizzo nei giochi online, è meglio esaminare le tue esigenze e capire la tua strategia di persistenza da quella, piuttosto che prendere il tuo database preferito e quindi provare a modificarlo con cache e replica per farlo corrispondere al tuo app. Potresti scoprire che tutto ciò di cui hai bisogno è la funzionalità di reporting offline, nel qual caso è probabilmente meglio avere un processo in background che registri dal meccanismo di persistenza del gioco in un RDBMS remoto da qualche altra parte.


4

Disclaimer: la mia esperienza di programmazione di gioco si basa su giochi single player lato client, ma ho un background in applicazioni web (in particolare nello stack Microsoft), quindi è da lì che provengo con questa risposta, penso che molto applicare, ma senza test reali di un vero server di gioco è difficile dire come verrà applicato, ma qui va. Sappi questo: non ho distribuito un server di gioco, solo webapps.

Suggerirei un approccio a due livelli (server). Un livello di database e un livello di "applicazione"; con il terzo livello (presentazione) il client di gioco.

Database relazionali, sono bravi a interrogare i dati e sono bravi a scrivere i dati. La chiave è serializzare le scritture del database in blocchi di dimensioni gestibili che il cluster può gestire. Le edizioni più avanzate (Data center / Enterprise) di SQL Server supportano il clustering e la replica. Vorrei iniziare creando un piccolo cluster ed eseguendo alcune query su di esso per vedere come funziona.

Nel livello dell'applicazione, se stai eseguendo una "suddivisione in zone" o qualcosa di simile, puoi probabilmente scappare senza impostare alcun cluster e semplicemente impostare un server per zona. Se le zone diventano troppo grandi, è possibile impostare un cluster per ogni zona.

È consigliabile creare un processo di serializzazione per l'invio di dati dal livello applicazione -> livello database. La chiave è avere diversi livelli di serializzazione in corso. Qualcosa del genere :

  • Livello 1: salva su DB ogni X secondi, include dati critici:
    • Salute del giocatore
    • Oggetti giocatore / Pickup
  • Livello 2: salva su DB ogni 2X secondi, include i dati medi:
    • Posizione dei giocatori
    • Posizioni NPC
  • Livello 3: tutto il resto, il più raramente possibile

Ciò manterrà le tue scritture coerenti e prevedibili, a seconda della natura del tuo gioco, potresti avere scritture di database rare. La chiave è rendersi conto che se il server delle applicazioni si arrestasse in modo anomalo, sarebbe necessario tornare online dallo stato nel database, quindi serializzare l'inventario dei giocatori ogni 90 minuti potrebbe rendere i giocatori sconvolti.

Per leggere i dati, ti consigliamo di caricare quanto più memoria possibile nel livello applicazione, quindi assicurarti che tutto il codice utilizzi questo pool di memoria, in background puoi sincronizzare il pool di memoria con il database. Come sottolinea Joe, ci saranno momenti in cui hai bisogno di transazioni "in tempo reale". Serializzando la maggior parte delle tue scritture, dovresti comunque avere un IO sufficiente sul tuo database per eseguire transazioni in tempo reale quando necessario, presumendo un hardware sufficiente sul server / cluster del database.


-1 perché hai appena lanciato ACID e stai solo usando il database come un grande archivio dati. Va bene, l'utilità di pianificazione del disco di Windows è abbastanza scadente che è ancora un guadagno in termini di prestazioni e probabilmente puoi fare alcune metriche offline ordinate con i dati al suo interno, ma hai ancora bisogno di ACID - cioè un database - che supporti le transazioni nel gioco stesso, in tempo reale (ish).

Mentre scarso, questo è quello che stavo andando nell'ultimo paragrafo. Sto raccomandando un po 'di un ibrido, dove usi IN-Memory dove possibile, e il database quando necessario.
Nate,

Il problema è che hai sorvolato ciò che è in memoria, che è un intero altro database, e non hai dato alcuna direzione su come implementarlo, che è il vero bit complicato.

È vero, sebbene la domanda riguardasse l'architettura di grandi dimensioni, non i dettagli di implementazione.
Nate,

Vero, ma hai lasciato fuori l'intero livello intermedio. È un RDB a bassa latenza? Un ODB? Chiave / archivio valori? Nessun DB e rinunciare all'ACID? STM o blocco? Ad essere sinceri, è molto difficile rispondere perché non ci sono molte informazioni nella domanda, ma tutta questa risposta al diagramma di architettura è prendere la grande bolla nel mezzo con un "?" in esso e collegare altri due servizi ad esso, in realtà non compilare cosa "?" è.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.