Quelle est la meilleure architecture de serveur pour les jeux en temps réel?

10

Je développe un jeu en temps réel qui devrait contenir des milliers de joueurs en temps réel (FPS comme. Max 1s lag). Quelle serait la meilleure infrastructure pour cela?

Mon idée était d'utiliser 2 clusters de serveurs - un pour le côté serveur (tout le côté informatique) et un pour la base de données, où un équilibreur de charge est "responsable" de chacun des clusters. Un serveur principal recevra les demandes des utilisateurs et renverra l'adresse IP du serveur concerné pour que l'utilisateur puisse travailler cela.

Le cluster de base de données utilisera la réplication de base de données pour assurer la cohérence entre les bases de données.

Il doit également y avoir un équilibreur de charge géographique - il affectera donc l'équilibreur de charge régional à chaque utilisateur pour une meilleure réponse.

J'utilise .NET + MSSQL pour le jeu.

Merci!

romain
la source
2
Quand vous dites «infrastructure», voulez-vous dire logiciel, matériel, services, ou vouliez-vous simplement que nous critiquions votre plan actuel tel quel?
Tetrad
1
@Nate - nous prévoyons d'évoluer, pas de dupliquer - il devrait donc être entièrement évolutif.
roman
2
-1 car teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html - Vous ne répondez à aucune exigence de capacité, vous dites que le jeu n'est pas fragmenté mais qu'il est zoné , etc. La nature des optimisations de performances - y compris l'évolutivité - nécessite des informations spécifiques et il n'existe pas de meilleure architecture absolue.
1
Je reformulerais votre question en quelque chose de plus concret. Qu'est-ce qui est «le meilleur», de manière factuelle et non subjective? Voulez-vous dire plus facile à mettre à l'échelle, plus facile à gérer, plus facile à démarrer, plus rapide ou quoi?
Le canard communiste
1
"Le plus simple" est également subjectif. Le plus simple pour qui, sur quelle période, avec quelles ressources? Les échanges de piles fonctionnent mieux avec des questions spécifiques - "J'ai construit ce serveur en utilisant LINQ et MSSQL, mais il est tombé après 70 transactions / seconde, voici mes deux principales transactions représentant 73% de mon temps d'exécution, comment dois-je augmenter mon débit? "

Réponses:

6

Il n'y a pas de meilleure architecture sans en savoir beaucoup plus sur vos besoins, par exemple. le type d'interactions entre les personnages, la quantité de données qui va être persistante, etc.

Si vous pouvez faire face à 1 seconde de latence, vous pouvez probablement héberger 1000 joueurs sur un seul serveur sans problèmes - mais cela entre en conflit avec l'idée d'un FPS car ils nécessitent généralement une latence beaucoup plus faible, par exemple. moins de 100 ms. Mais un système qui peut gérer une latence élevée peut se permettre de tout faire via le passage de messages, ce qui rend la cohérence assez triviale. Fournir votre logique est assez simple, c'est-à-dire qu'une logique complexe devient encore pire lorsque vous la transformez en un système basé sur des messages plutôt qu'un système d'objet verrouillé - mais tout dépend des besoins de votre application.

De même, si vous ne conservez pas beaucoup de données, vous n'avez pas du tout besoin de la machine de base de données, mais sans le savoir, c'est difficile à dire. Si vous persistez de petites quantités de données, et peut-être seulement le faire à la fin d'un tournoi ou quelque chose, encore une fois, vous n'avez pas besoin d'une base de données distincte, certainement pas un cluster d'entre eux. D'un autre côté, si vous ne persistez pas beaucoup mais que vous lisez beaucoup, c'est là que les bases de données répliquées peuvent vous aider - mais cela indique également qu'une base de données relationnelle peut ne pas être la meilleure correspondance pour votre problème en premier lieu. Souvent, un cache en mémoire est une meilleure solution. De même, s'il n'y a pas d'interactions de type transaction entre les personnages, la cohérence devient moins importante. (Et s'il n'y a que quelques transactions de ce type, vous pouvez en faire un cas spécial.)

En fait, méfiez-vous d'adopter un SGBDR juste parce que c'est chose faite dans les grands systèmes. Bien que j'approuve personnellement de les utiliser dans les jeux en ligne, il est préférable de regarder vos besoins et de comprendre votre stratégie de persistance à partir de cela, plutôt que de prendre votre base de données préférée et d'essayer de la peaufiner avec des caches et de la réplication pour l'adapter à votre app. Vous pouvez constater que tout ce dont vous avez besoin est une capacité de rapport hors ligne, auquel cas il est probablement préférable d'avoir un processus d'arrière-plan qui se connecte à partir de votre mécanisme de persistance de jeu dans un SGBDR distant ailleurs.

Kylotan
la source
4

Avertissement: mon expérience de programmation de jeux est basée sur des jeux solo côté client, mais j'ai une expérience dans les applications Web (en particulier sur la pile Microsoft), c'est donc de là que je viens avec cette réponse, je pense que beaucoup appliquer, mais sans tester réellement un vrai serveur de jeu, il est difficile de dire comment il s'appliquera, mais voilà. Sachez ceci: je n'ai pas déployé de serveur de jeu, seulement des webapps.

Je suggérerais une approche à deux niveaux (serveur). Un niveau base de données et un niveau "application"; avec le troisième niveau (présentation) étant votre client de jeu.

Les bases de données relationnelles sont excellentes pour interroger des données et décentes pour écrire des données. La clé est de sérialiser vos écritures de base de données en morceaux de taille gérable que votre cluster peut gérer. Les éditions les plus avancées (centre de données / entreprise) de SQL Server prennent en charge la mise en cluster et la réplication. Je commencerais par créer un petit cluster et exécuter des requêtes sur lui pour voir comment cela fonctionne.

Dans le niveau application, si vous effectuez un "zonage" ou quelque chose de similaire, vous pouvez probablement vous en sortir sans configurer de cluster, et simplement configurer un serveur par zone. Si vos zones deviennent trop grandes, vous pouvez configurer un cluster pour chaque zone.

Vous souhaiterez créer un processus de sérialisation pour envoyer des données à partir du niveau application -> niveau base de données. La clé est d'avoir plusieurs niveaux de sérialisation en cours. Quelque chose comme ça:

  • Niveau 1: Enregistrer dans la base de données toutes les X secondes, inclut les données critiques:
    • Santé des joueurs
    • Objets / micros des joueurs
  • Niveau 2: enregistrer dans la base de données toutes les 2X secondes, comprend des données moyennes:
    • Emplacements des joueurs
    • Emplacements des PNJ
  • Niveau 3: tout le reste, aussi rarement que possible

Cela gardera vos écritures cohérentes et prévisibles, selon la nature de votre jeu, vous pourriez avoir des écritures de base de données peu fréquentes. La clé est de réaliser que si votre serveur d'applications tombe en panne, vous devrez revenir en ligne à partir de l'état de votre base de données, de sorte que la sérialisation de l'inventaire des joueurs toutes les 90 minutes pourrait perturber les joueurs.

Pour lire les données, vous souhaiterez charger autant que possible en mémoire dans le niveau d'application, puis assurez-vous que tout votre code utilise ce pool de mémoire.En arrière-plan, vous pouvez synchroniser le pool de mémoire avec la base de données. Comme Joe le souligne, il y aura des moments où vous aurez besoin de transactions «en temps réel». En sérialisant la plupart de vos écritures, vous devriez toujours avoir suffisamment d'E / S sur votre base de données pour effectuer des transactions en temps réel si nécessaire, en supposant que le matériel est suffisant sur le serveur / cluster de base de données.

Nate
la source
-1 parce que vous venez de jeter ACID et que vous utilisez simplement la base de données comme magasin de données volumineuses. C'est bien, le planificateur de disque de Windows est assez merdique qui est toujours un gain de performances, et vous pouvez probablement faire des métriques hors ligne soignées avec les données qu'il contient, mais vous avez toujours besoin d'ACID - c'est-à-dire d'une base de données - pour sauvegarder les transactions dans le jeu lui-même, en temps réel (ish).
Bien que clairsemé, c'est ce vers quoi je me dirigeais dans le dernier paragraphe. Je recommande un peu un hybride, où vous utilisez IN-Memory si possible, et la base de données si nécessaire.
Nate
Le problème est que vous avez passé sous silence ce qui est en mémoire, qui est une toute autre base de données, et vous n'avez donné aucune indication sur la façon de l'implémenter, ce qui est le bit délicat.
Certes, bien que la question porte sur l'architecture globale, pas sur les détails de mise en œuvre.
Nate
Certes, mais vous avez omis tout le niveau intermédiaire. Est-ce un RDB à faible latence? Un ODB? Magasin de clés / valeur? Pas de DB et abandonner ACID? STM ou verrouillage? Pour être honnête, il est très difficile de répondre à cela car il n'y a pas beaucoup d'informations dans la question, mais toute cette réponse au diagramme d'architecture consiste à prendre la grosse bulle au milieu avec un "?" et connectez-y deux autres services, ne remplissez pas réellement "?" est.