La couche qui gère réellement les données des joueurs sur un serveur Metin2 n'est pas le cœur du jeu, comme on le croit souvent, mais le processus metin2 db cache. Lorsque vous déplacez un personnage, ramassez un objet ou terminez une quête, aucune de ces actions ne va directement vers MySQL. Elles passent d'abord par une couche de cache en mémoire. Dans cet article, j'explique pas à pas comment le processus db conserve les données des joueurs, quand il écrit sur le disque et pourquoi cette architecture est aussi répandue.
L'architecture multi-processus de Metin2
Un serveur Metin2 classique n'est pas un programme unique. Il se compose d'au moins trois processus distincts, chacun ayant son propre rôle :
- auth — Gère la connexion et la vérification des comptes. Il contrôle le nom d'utilisateur et le mot de passe, puis délivre une clé de session.
- db — La porte unique de tout le trafic MySQL. Il charge les données des joueurs en mémoire, les met en cache et les réécrit périodiquement dans la base.
- game / core — Le jeu lui-même. Le déplacement, le combat, les quêtes, les PNJ et la logique des cartes s'exécutent ici. Les grands serveurs lancent plusieurs processus
core(canaux).
Le point essentiel : les cœurs du jeu ne parlent jamais directement à MySQL. Toutes les requêtes de lecture et d'écriture sont envoyées au processus db via un protocole TCP personnalisé. Le processus db répond à ces requêtes, interroge MySQL si nécessaire, et la plupart du temps répond à partir de la copie qu'il garde déjà en mémoire.
Pourquoi le db cache existe-t-il ?
Cette couche supplémentaire peut sembler être une complexité inutile au premier abord. Son but est pourtant très concret : protéger MySQL d'un flot constant de requêtes. Pensez aux données de position, de vie, d'expérience et d'inventaire que des centaines de joueurs modifient des dizaines de fois par seconde. Écrire immédiatement chaque modification dans la base serait une charge que le disque et InnoDB ne pourraient tout simplement pas supporter.
Le db cache résout ce problème ainsi :
- Quand un joueur se connecte, toutes ses données (personnage, inventaire, quêtes, affects, coffre) sont lues une seule fois depuis MySQL et conservées en mémoire.
- Toutes les modifications en jeu sont d'abord appliquées sur cette copie mémoire — elles ne touchent pas le disque.
- Les écritures dans la base sont regroupées et effectuées à intervalles fixes, ainsi qu'à la déconnexion du joueur.
Résultat : le nombre d'écritures atteignant MySQL chute par milliers, tandis que les opérations en jeu répondent à la vitesse de la mémoire.
Comment les données du joueur sont-elles chargées en mémoire ?
Lorsqu'un joueur sélectionne un personnage, le processus db rassemble toutes les données de ce personnage depuis les tables concernées. Dans Metin2, les données d'un joueur ne résident pas dans une seule table ; elles sont logiquement réparties :
player— le personnage de base (niveau, expérience, position, statistiques)item— inventaire, coffre et objets équipésquest— état et indicateurs des quêtesaffect— effets de buff/débuff actifssafeboxetmall— stockage et coffre de la boutique
Ces lignes sont fusionnées en mémoire dans un objet de cache lié au personnage. Tant que le joueur reste en ligne, cet objet vit ; pour chaque requête de données, le cœur consulte cet objet plutôt que MySQL.
Quand les données sont-elles écrites sur le disque ?
La logique de sauvegarde est la partie la plus critique de cette architecture, car la plupart des pertes des joueurs (duplications d'objets, rollbacks, objets disparus) y prennent naissance. Les données sont écrites dans MySQL dans trois situations :
- Sauvegarde périodique : à intervalles fixes, le processus db parcourt les enregistrements « sales » (modifiés) en mémoire et les écrit dans MySQL sous forme d'instructions
UPDATE. Cet intervalle dépend de la configuration ; c'est généralement une fenêtre de quelques secondes. - Sauvegarde à la déconnexion : quand un joueur quitte le jeu ou que la connexion tombe, toutes les données de ce personnage sont écrites immédiatement sur le disque et retirées du cache.
- Sauvegarde immédiate sur événements critiques : pour les opérations sensibles comme la création de monnaie ou les transactions de coffre, les données peuvent être écrites sans attendre.
C'est précisément pour cela que, si un serveur plante de manière inattendue (kill -9, panne matérielle, OOM), toutes les modifications postérieures à la dernière sauvegarde périodique sont perdues — d'où le « rollback » que vivent les joueurs. L'avantage de vitesse de l'architecture est en même temps son plus grand point de risque.
La communication entre le cœur et db
Le dialogue entre le cœur du jeu et db passe par un protocole personnalisé basé sur des paquets. Un cœur envoie un paquet du type « charge les données de ce joueur » ou « mets à jour cet objet », le processus db le met en file, le traite et renvoie la réponse. Cette structure garantit la cohérence à partir d'une source unique faisant autorité (db) lorsque plusieurs processus core partagent le même bassin de joueurs.
Côté configuration, la connexion est généralement établie avec des lignes comme celles-ci :
PLAYER_SQL: localhost player root motdepasse
COMMON_SQL: localhost common root motdepasse
# adresse du processus db côté core
db_addr: 127.0.0.1
db_port: 15000
On y voit deux bases de données distinctes : player (données spécifiques au joueur, en constante évolution) et common (tables de définition en lecture seule comme item_proto et mob_proto). Les données common changent rarement et sont donc fortement mises en cache ; les données player sont celles que le db cache gère réellement.
Conseils pour une bonne gestion du db cache
- Gardez un intervalle de sauvegarde équilibré : un intervalle trop long augmente le risque de rollback, un intervalle trop court fatigue MySQL. Réglez-le selon la charge de votre serveur.
- Surveillez le processus db : si db plante, aucune donnée ne peut être sauvegardée même si les cœurs restent debout. Surveillez toujours la santé du processus.
- Utilisez InnoDB : préférez InnoDB à MyISAM pour les tables player ; cela fait une différence pour la cohérence après plantage et les écritures concurrentes.
- Faites des sauvegardes : une sauvegarde régulière par
mysqldumpest le seul moyen sûr de compenser la perte de données inévitable dans la fenêtre de sauvegarde périodique.
Questions fréquentes
Les données du joueur sont-elles perdues si le db cache plante ?
Toutes les modifications accumulées après la dernière sauvegarde périodique sont perdues. Si le processus db s'arrête proprement (graceful shutdown), il vide les données mémoire sur le disque ; lors d'un plantage soudain (kill -9), seules les données jusqu'au dernier point de sauvegarde sont en sécurité.
Pourquoi le cœur ne se connecte-t-il pas directement à MySQL ?
Pour la performance et la cohérence. Un seul processus db regroupe la charge d'écriture pour protéger MySQL et agit comme source de données unique faisant autorité entre plusieurs cœurs, évitant les conflits de données.
Quelle est la différence entre les bases player et common ?
player contient les données en constante évolution appartenant au joueur (personnage, objets, quêtes) et est gérée par le db cache. common contient les tables de définition rarement modifiées comme item_proto et mob_proto et est principalement lue.
Vous rencontrez des pertes de données, des rollbacks ou des problèmes de performance sur votre serveur Metin2 ? Examinons ensemble votre configuration db cache et votre architecture de base de données. Contactez-moi.