Je veux utiliser la base de données SQL dans mon server.exe.
disons 1000 utilisateurs en ligne. Et les joueurs changeront leurs données lorsqu'ils joueront. Et le serveur doit enregistrer ces mises à jour.
Mais comment ?
je pense qu'il y a deux sens:
1) le serveur enregistre dans le ram au moment de l'exécution et parfois ou toutes les heures, le serveur écrit les données (mise à jour) dans la base de données SQL à partir du ram. Mais si l'électricité se coupe ou que le serveur s'arrête, les mises à jour ne seront pas enregistrées. bien sûr, je ne veux pas perdre les mises à jour.
2) le serveur enregistrera les mises à jour dans la base de données au moment de l'exécution. mais qu'arrivera-t-il pour accélérer? J'ai pensé à une méthode. je vais vous montrer ci-dessous avec l'image. Puis-je obtenir suffisamment de vitesse pour 1000 joueurs en ligne avec cette méthode?
la source
Réponses:
La plupart des MMO (ou projets utilisant une architecture similaire) sur lesquels j'ai travaillé ou que je connais utilisent la première méthode: les serveurs de jeux fonctionnent principalement avec la RAM sur les machines exécutant les processus serveur et ne sérialisent que périodiquement les données de jeu pertinentes dans une base de données SQL pour l'archivage (s'il y en a un).
Les problèmes que vous notez concernant la panne de courant sont valides, mais moins susceptibles que des problèmes tels que les plantages dans le processus (la fiabilité de la disponibilité est généralement l'une de ces choses pour lesquelles vous paieriez le centre de données). Mais reste. Vous atténuez ces problèmes grâce à des choses comme le réglage de l'intervalle de sauvegarde (donc une panne ne coûte que quelques minutes au maximum), la distribution des files d'attente de sauvegarde sur plusieurs machines, l'étendue agressive de la quantité de données qui doit être sauvegardée et l'implémentation de la sauvegarde redémarrable files d'attente.
De manière générale, l'utilisation du serveur SQL lui-même comme mémoire principale sera désagréablement lente (et lourde). Je ne vois pas suffisamment de détails dans votre proposition pour pouvoir dire avec certitude si cela fonctionnerait pour seulement environ 1000 joueurs - ce serait probablement bien. Mais je ne pense pas que vous puissiez le rendre évolutif de manière agressive.
De plus, cela ne résout pas le problème. Une panne de courant pendant le processus de sauvegarde perdra ou corrompra des données, sauf si vous effectuez le travail pour implémenter le même type de file d'attente de sauvegarde redémarrable (ce qui, même alors, ne réduit que gravement la probabilité de perte de données catastrophique, il ne l'empêche pas) .
Je vous recommande d'aller avec la première approche.
la source
Le joueur 1000 peut ou peut ne pas être un problème. Cela dépend de la fréquence à laquelle vous devez mettre à jour la base de données. Cependant, il existe une solution simple: mettre la base de données sur son propre serveur.
J'ai eu un aperçu du fonctionnement du système de base de données un jeu que les gens appellent un MMO-Lite - lequel je ne divulguerai pas - mais je peux dire qu'il a toujours plus de 1000 joueurs, voici le résumé:
L'utilisation d'une base de données basée sur des documents s'avère être une bonne idée de performances dans ce cas. C'est bon pour accéder aux données, même si c'est mauvais pour faire des jointures et des agrégations ... mais ils ne le feront pas avec les données qui s'y trouvent.
D'un autre côté, quand ils doivent faire quelque chose comme changer un objet avec un autre objet pour tout le monde, la nécessité d'exécuter un script d'arrière-plan qui va caractère par caractère et les met à jour un par un, cela prend du temps.
Les données du personnage existent à la fois sur le client et sur le serveur, et le système est conçu pour les synchroniser, en effectuant les mêmes opérations des deux côtés.
Désormais, lorsqu'un joueur effectue une transaction avec le système - disons échanger un objet contre un autre via un PNJ ou similaire - cela comporte les étapes suivantes:
Remarques :
Les échanges entre les joueurs sont traités de la même manière, avec des règles supplémentaires pour empêcher les joueurs d'escroquer d'autres joueurs et une traçabilité supplémentaire au cas où une transaction devrait être annulée. J'ai entendu dire qu'il existe des journaux spéciaux de toutes les transactions qui sont conservées pendant un certain temps (pour résoudre les problèmes lorsque quelqu'un se plaint), je ne sais pas plus comment cette partie fonctionne.
Parfois, quelque chose ne va pas, cela a deux résultats possibles:
Dans les deux cas, le client est conscient de l'erreur et l'enregistrera avec tout ce que le joueur faisait. La journalisation côté client se produit tout le temps. Ensuite, à la déconnexion, en cas d'erreur, le client envoie les journaux au serveur.
Ce jeu n'utilise pas le temps d'arrêt d'entretien quotidien ou hebdomadaire traditionnel de la plupart des MMORPG. Cette maintenance planifiée est souvent utilisée pour réinitialiser les compteurs, les minuteurs et exécuter les procédures de base de données. Ils sont également l'occasion d'échanger des versions de serveur pour une mise à jour.
la source
x:10,y:10,z:10
Àx:11,y:11,z:11
, cela devrait-il être enregistré immédiatement dans la base de données? que se passe-t-il si le joueur continue de fonctionner, cela signifie que nous enregistrons sa position actuelle toutes les 1s ou moins, et s'il y a des milliers de joueurs, c'est des millions de requêtes à la base de données chaque seconde. Est-ce ainsi que cela fonctionne?Les deux approches sont utilisées avec les MMORPG. Garder tout en mémoire et vérifier périodiquement le pointer vers le disque semble être l'option la plus populaire, au moins pour les jeux plus anciens. Il a l'avantage d'être assez simple à implémenter et à évoluer assez bien, mais sa fiabilité est entièrement à la charge du développeur. Les bases de données SQL fournissent des propriétés ACID qui facilitent la fiabilité, mais sont globalement plus compliquées à mettre en œuvre correctement et peuvent avoir des problèmes de mise à l'échelle.
EVE Online est un exemple de MMO où tout est stocké dans une base de données SQL. Je pense qu'il a culminé à quelque 60 000 utilisateurs simultanés et a dû consacrer du matériel coûteux aux serveurs de base de données au fil des ans afin de suivre la charge. Cependant, EVE stocke beaucoup plus de données par utilisateur que la plupart des MMORPG et a des transactions beaucoup plus fréquentes et variées. Les propriétés ACID de la base de données permettent à l'ensemble de la base de données massive et compliquée d'être toujours maintenue dans un état cohérent.
Par exemple, considérons le cas où quelqu'un donne un objet à un autre joueur. La base de données d'EVE garantit que même en cas de crash ou de panne de courant, l'objet se retrouve dans l'inventaire d'un seul joueur. Autrement dit, la transaction de base de données qui supprime l'élément de l'inventaire d'un joueur et l'ajoute à celui de l'autre joueur est atomique. La transaction se termine complètement ou ne se produit pas du tout. Vous ne pouvez pas vous retrouver dans un état où l'objet n'existe dans l'inventaire des joueurs ou dans les deux.
Un MMORPG qui garde les données des joueurs en mémoire et vérifie périodiquement les points qu'il doit mettre en œuvre lui-même cette atomicité. Une façon de le faire serait de vérifier les données de chaque joueur en même temps, en s'assurant que le nouveau point de contrôle est entièrement validé sur le disque avant d'être considéré comme le point de contrôle le plus récent. Le jeu devrait également garantir que les données des joueurs ne peuvent pas changer pendant leur contrôle. Avec une grande quantité de joueurs actifs, le défi devient de faire tout cela sans causer un retard suffisamment long pour que les joueurs le remarquent.
Ne sous-estimez pas l'importance de la cohérence. Lorsque vous développez votre jeu, ça va planter beaucoup. Vous ne voulez pas avoir à rechercher pourquoi les éléments disparaissent et / ou dupliquent, pas lorsque le problème est un bug sans rapport qui provoque le crash du jeu à un mauvais moment. De plus, lorsque votre jeu sera mis en ligne, il plantera beaucoup plus que vous ne le pensez. Votre serveur qui fonctionnait parfaitement sous test, exposera soudainement de nombreux bogues à pleine charge et les joueurs font ce que vous ne vous attendiez pas.
Notez que la plupart des MMORPG utilisent des bases de données SQL pour les informations liées aux comptes, même si elles ne le sont pas pour les données de jeu réelles. Encore plus important que de maintenir l'état du jeu dans un état cohérent est de maintenir l'état de facturation cohérent. Le pire cas de corruption de la base de données du jeu est que vous devez restaurer la base de données à partir d'une sauvegarde quotidienne. Le pire cas de corruption de la base de données des comptes est que vous faites faillite en raison de tous les débits compensatoires.
Pour votre projet, vous pouvez probablement aller dans les deux sens. Avoir 1000 utilisateurs simultanés ne repoussera probablement pas les limites de ce qu'un serveur SQL peut gérer sur un PC standard ces jours-ci, mais beaucoup dépendra de la nature des transactions. Si vous êtes familier avec la conception de bases de données relationnelles et SQL, cela peut fonctionner pour vous. Vous souhaiterez minimiser les transactions autant que possible, pour quelque chose comme les points de vie actuels des joueurs, vous ne voudrez peut-être que les enregistrer périodiquement dans la base de données, car ces statistiques n'ont pas nécessairement besoin d'être cohérentes. (Dans le jeu PvP, ils pourraient cependant ...) Ne stockez pas du tout les monstres HP dans la base de données, dans la plupart des jeux, seules les données relatives aux joueurs sont persistantes.
D'un autre côté, si vous n'êtes pas un assistant SQL, vous trouverez peut-être beaucoup plus simple de conserver toutes les données en mémoire pour travailler de manière fiable. Les bases de données SQL facilitent la cohérence et la fiabilité, mais ce n'est pas automatique. Une base de données mal conçue peut mal fonctionner et entraîner des incohérences. Les transactions ne seront atomiques que si vous le faites. Si vous n'utilisez pas religieusement des instructions paramétrées, vous vous exposerez aux attaques par injection SQL.
la source
Divers jeux stockent les choses de différentes manières. Souvent, les sociétés de jeux créent un moyen de le faire, et la plupart de leurs jeux utilisent la même manière. Bien sûr, différents studios utilisent souvent des méthodes différentes. SQL est certainement utilisé pour les jeux, par exemple CCP (EVE) a (ou du moins avait) un réseau de serveurs SQL, je ne sais pas comment ils le font maintenant. Pour d'autres, il suffit d'utiliser de nombreux fichiers.
Peut-être commencer par créer un "mécanisme de courtage de données" agnostique, pour gérer diverses transactions de données de jeu? Comme vous ne faites que tester de toute façon, créez un mécanisme qui vous permet de ne pas trop vous soucier du stockage, du point de vue du jeu lui-même. C'est-à-dire, concentrez-vous sur la façon dont, à partir de l'application hôte, vous allez gérer cela.
Personnellement, je pense que ce serait un grand atout si vous pouviez changer de magasin, sans avoir à réécrire le jeu et le courtier lui-même. Passez simplement à un autre module avec la même interface pour que le courtier puisse parler.
Le stockage des données en soi ne sera probablement pas un problème en soi. Expédier efficacement des données, vers / depuis ce magasin, entre l'hôte et tous les clients, pourrait être plus délicat. Dois-je expédier l'ensemble des données du lecteur, ou si je le décompose en parties, quelle granularité dois-je choisir de partitionner, etc. Laquelle est la plus gourmande en ressources dans quelle situation, etc.
Un format dans lequel envoyer les données pourrait être XML. De cette façon, vous pouvez plus facilement être dynamique dans la façon dont vous pouvez le fragmenter. Un caractère par rapport à plusieurs caractères, ou un élément par rapport à une collection d'éléments, etc. Vous pouvez alors soit «stocker» le XML en XML (en SQL), et / ou demander à SQL de le distribuer de manière plus transactionnelle à partir du XML, vers comment vous voulez que les données soient réellement stockées.
Une autre façon est binaire, qui est plus efficace en termes d'expédition, mais peut entraîner des coûts plus élevés dans d'autres situations.
Avec 1000 clients, vous pouvez commencer et stocker facilement 10 Mo par client et n'utiliser que 10 Go de RAM efficace + ajouter de la RAM administrative système pour gérer ces données, disons un autre Go ou deux. Vous pouvez garder cela en RAM sur l'hôte déjà dans la structure de données prêt à l'emploi. Et chargez / enregistrez dynamiquement, selon qui est en ligne, à différentes fréquences selon l'activité, etc.
Vous pouvez même stocker les informations de chaque client dans un fichier séparé, etc.
la source
Gardez les joueurs * en ligne * dans ram et poussez-les dans une base de données (SQLite? MySQL?) Lorsqu'ils se déconnectent. si vous vous inquiétez du blocage des entrées-sorties pendant la déconnexion, donnez à chaque déconnexion son propre fil de discussion, ne le faites pas dans le fil principal / jeu (en fait, je garde un fil de lecteur dédié pour chaque joueur en ligne, cela a rendu le code de mise en réseau tellement plus facile que de faire l'approche réseau io asynchrone)
la source