Die Schicht, die auf einem Metin2-Server die Spielerdaten tatsächlich verwaltet, ist nicht der Game-Core, wie viele annehmen, sondern der metin2 db cache-Prozess. Wenn du einen Charakter bewegst, ein Item aufhebst oder eine Quest abschließt, gelangt keine dieser Aktionen direkt zu MySQL. Sie laufen zuerst durch eine Cache-Schicht im Arbeitsspeicher. In diesem Artikel zeige ich Schritt für Schritt, wie der db-Prozess Spielerdaten hält, wann er auf die Festplatte schreibt und warum diese Architektur so verbreitet ist.
Die Mehrprozess-Architektur von Metin2
Ein klassischer Metin2-Server ist kein einzelnes Programm. Er besteht aus mindestens drei getrennten Prozessen, von denen jeder eine eigene Aufgabe hat:
- auth — Übernimmt das Einloggen und die Kontoprüfung. Es prüft Benutzername und Passwort und stellt einen Sitzungsschlüssel aus.
- db — Das einzige Tor für den gesamten MySQL-Verkehr. Es lädt Spielerdaten in den Speicher, cacht sie und schreibt sie regelmäßig in die Datenbank zurück.
- game / core — Das Spiel selbst. Bewegung, Kampf, Quests, NPCs und Kartenlogik laufen hier. Größere Server betreiben mehrere
core-Prozesse (Kanäle).
Der entscheidende Punkt: die Game-Cores sprechen niemals direkt mit MySQL. Jede Lese- und Schreibanfrage wird über ein eigenes TCP-Protokoll an den db-Prozess geschickt. Der db-Prozess beantwortet diese Anfragen, fragt bei Bedarf MySQL ab und antwortet meistens aus der Kopie, die er bereits im Speicher hält.
Warum gibt es den db cache?
Diese zusätzliche Schicht wirkt auf den ersten Blick vielleicht wie unnötige Komplexität. Ihr Zweck ist jedoch sehr konkret: MySQL vor ständigen Abfragen zu schützen. Denk an Positions-, Lebens-, Erfahrungs- und Inventardaten, die Hunderte von Spielern Dutzende Male pro Sekunde ändern. Jede einzelne Änderung sofort in die Datenbank zu schreiben, wäre eine Last, die Festplatte und InnoDB schlicht nicht bewältigen könnten.
Der db cache löst das folgendermaßen:
- Wenn sich ein Spieler einloggt, werden alle seine Daten (Charakter, Inventar, Quests, Affects, Lager) einmal aus MySQL gelesen und im Speicher gehalten.
- Alle Änderungen im Spiel werden zuerst an dieser Speicherkopie vorgenommen — sie berühren die Festplatte nicht.
- Schreibvorgänge in die Datenbank werden gebündelt und in festen Intervallen sowie beim Ausloggen des Spielers ausgeführt.
Das Ergebnis: Die Zahl der Schreibvorgänge, die MySQL erreichen, sinkt um das Tausendfache, während Aktionen im Spiel in Speichergeschwindigkeit reagieren.
Wie werden Spielerdaten in den Speicher geladen?
Wenn ein Spieler einen Charakter auswählt, sammelt der db-Prozess alle Daten dieses Charakters aus den entsprechenden Tabellen. In Metin2 liegen die Spielerdaten nicht in einer einzigen Tabelle; sie sind logisch aufgeteilt:
player— der Basis-Charakter (Level, Erfahrung, Position, Werte)item— Inventar, Lager und ausgerüstete Itemsquest— Queststatus und Flagsaffect— aktive Buff-/Debuff-Effektesafeboxundmall— Lager und Mall-Tresor
Diese Zeilen werden im Speicher zu einem Cache-Objekt zusammengeführt, das an den Charakter gebunden ist. Solange der Spieler online bleibt, lebt dieses Objekt; bei jeder Datenabfrage konsultiert der Core dieses Objekt anstelle von MySQL.
Wann werden Daten auf die Festplatte geschrieben?
Die Speicherlogik ist der kritischste Teil dieser Architektur, denn die meisten Spielerverluste (Item-Dupes, Rollbacks, verschwundene Items) entstehen hier. Daten werden in drei Situationen nach MySQL geschrieben:
- Periodisches Speichern: In festen Intervallen durchsucht der db-Prozess die "schmutzigen" (geänderten) Datensätze im Speicher und schreibt sie als
UPDATE-Anweisungen nach MySQL. Dieses Intervall hängt von der Konfiguration ab; typischerweise ist es ein Verzögerungsfenster von wenigen Sekunden. - Speichern beim Ausloggen: Wenn ein Spieler das Spiel verlässt oder die Verbindung abbricht, werden alle Daten dieses Charakters sofort auf die Festplatte geschrieben und aus dem Cache entfernt.
- Sofortiges Speichern bei kritischen Ereignissen: Bei sensiblen Vorgängen wie dem Erzeugen von Währung oder Tresor-Transaktionen können Daten ohne Wartezeit weggeschrieben werden.
Genau deshalb gehen bei einem unerwarteten Absturz (kill -9, Hardwarefehler, OOM) alle Änderungen nach dem letzten periodischen Speichern verloren — daher der "Rollback", den Spieler erleben. Der Geschwindigkeitsvorteil der Architektur ist zugleich ihr größter Risikopunkt.
Die Kommunikation zwischen Core und db
Der Austausch zwischen dem Game-Core und db läuft über ein eigenes, paketbasiertes Protokoll. Ein Core sendet ein Paket wie "lade die Daten dieses Spielers" oder "aktualisiere dieses Item", der db-Prozess stellt es in die Warteschlange, verarbeitet es und sendet die Antwort zurück. Diese Struktur sichert Konsistenz aus einer einzigen autoritativen Quelle (db), wenn mehrere core-Prozesse denselben Spielerpool teilen.
Auf der Konfigurationsseite wird die Verbindung meist mit Zeilen wie diesen eingerichtet:
PLAYER_SQL: localhost player root passwort
COMMON_SQL: localhost common root passwort
# Adresse des db-Prozesses auf der Core-Seite
db_addr: 127.0.0.1
db_port: 15000
Hier siehst du zwei getrennte Datenbanken: player (spielerspezifische, sich ständig ändernde Daten) und common (schreibgeschützte Definitionstabellen wie item_proto und mob_proto). Die common-Daten ändern sich selten und werden daher stark gecacht; die player-Daten sind das, was der db cache tatsächlich verwaltet.
Tipps für ein gutes db-cache-Management
- Halte das Speicherintervall ausgewogen: Ein zu langes Intervall erhöht das Rollback-Risiko, ein zu kurzes Intervall belastet MySQL. Stimme es auf deine Serverlast ab.
- Überwache den db-Prozess: Wenn db abstürzt, können keine Daten gespeichert werden, selbst wenn die Game-Cores weiterlaufen. Überwache immer die Gesundheit des Prozesses.
- Verwende InnoDB: Bevorzuge InnoDB gegenüber MyISAM für die player-Tabellen; das macht bei der Konsistenz nach einem Absturz und bei gleichzeitigen Schreibvorgängen einen Unterschied.
- Erstelle Backups: Ein regelmäßiges
mysqldump-Backup ist der einzige sichere Weg, den unvermeidlichen Datenverlust innerhalb des periodischen Speicherfensters auszugleichen.
Häufige Fragen
Gehen Spielerdaten verloren, wenn der db cache abstürzt?
Alle Änderungen, die sich nach dem letzten periodischen Speichern angesammelt haben, gehen verloren. Wenn der db-Prozess sauber herunterfährt (graceful shutdown), schreibt er die Speicherdaten auf die Festplatte; bei einem plötzlichen Absturz (kill -9) sind nur die Daten bis zum letzten Speicherpunkt sicher.
Warum verbindet sich der Core nicht direkt mit MySQL?
Aus Gründen der Leistung und Konsistenz. Ein einzelner db-Prozess bündelt die Schreiblast, um MySQL zu schützen, und fungiert als die eine autoritative Datenquelle über mehrere Cores hinweg, wodurch Datenkonflikte verhindert werden.
Was ist der Unterschied zwischen der player- und der common-Datenbank?
player enthält die sich ständig ändernden Daten, die zum Spieler gehören (Charakter, Items, Quests), und wird vom db cache verwaltet. common enthält selten geänderte Definitionstabellen wie item_proto und mob_proto und wird überwiegend gelesen.
Hast du auf deinem Metin2-Server mit Datenverlust, Rollbacks oder Leistungsproblemen zu kämpfen? Lass uns gemeinsam deine db-cache-Konfiguration und deine Datenbank-Architektur durchgehen. Nimm Kontakt mit mir auf.