Relationale Datenbank: In-RAM-Partitionierung? Theoretische Strukturdiskussion


7

Ich schreibe eine MMORPG-Server-Engine mit einigen eher esoterischen Elementen um (theoretisch gut, aber in der Praxis selten verwendet) und habe ein wenig Zweifel. Einige Elemente davon sind „solide“ - aber der Sinn von „Noch ein MMO-Server“ besteht darin, einige dieser Konzepte in Code auf Produktionsebene zu testen.

Ich hoffe jedoch, dass hier jemand praktische Erfahrungen mit PostgreSQL-Partitionierungsmodellen hat und in der Lage ist, diesem Projekt jedoch etwas Fachwissen zu verleihen.

Überblick

Es gibt eine TL; DR-Version unten.

  • Die Kernstruktur des Betriebssystems ist ein Cluster von Linux-Instanzen, möglicherweise auf einem Cloud-System. Stubs zur Überwachung der Gesamtsystemleistung und zum Hochfahren neuer Instanzen mithilfe einer externen API sind für die spätere Implementierung geplant. Zu Testzwecken versuchen wir wahrscheinlich, Amazon zu verwenden, aber wir lassen die Tür offen, um daraus ein steckbares Modul für z. B. RackSpace und andere Anbieter zu machen oder sogar einige ungezogene Dinge mit der Neukonfiguration eines Pools von physischen, "heißen Standby" -Modulen zu tun. Server auf einem privaten Rack.
  • Die Hauptlogik des MMO basiert auf einem „reinen“ Entity-Component-System-Modell. Entitäten sind lange Ganzzahl-IDs. Komponenten sind relationale Datensätze oder Sätze (Listen) von Datensätzen (JOINable-Referenzen); Systeme sind Funktionen. Systeme stellen Metadaten darüber bereit, auf welche Komponenten sie zugreifen müssen, und die Methode ← → Datenlokalität im gesamten Cluster basiert auf einem Planer, der diese Zugriffe vorwegnimmt und versucht, dieselben Systeme auf denselben Hosts auszuführen. Das heißt: Systeme, die auf dieselbe Komponente derselben Entität zugreifen, befinden sich in der Regel auf demselben Computer.
  • Der relationale Datenspeicher wird von einer PostgreSQL-Datenbank unterstützt. Dies wurde ausgewählt, weil es sich um freie Software handelt und (für unsere Zwecke) in einigen Punkten „bessere“ SQL / ACID-Dienste als MySQL bietet. Nehmen wir an, dies ist unveränderlich (es wurde bereits viel darüber gestritten).
  • Die Server-Host-Instanzen stellen eine einzelne Spielwelt dar, die einen zusammenhängenden koordinierten Raum einnimmt: In der Spielwelt gibt es per se keine Diskontinuitäten (z. B. Ebenen; Sternensysteme; Weltinstanzen). Daher können die Entitäten basierend auf dynamischen Regionen auf Hosts aufgeteilt werden, deren „Größe“ sich zur Laufzeit ändern kann. Es ist selbstverständlich, dass solche Regionen in SQL mehr oder weniger effizient partitioniert werden können: z. B. können wir eine „Partitionsebene bei Y = -10“ definieren und die Entitäten basierend auf ihren Y-Koordinaten oder ähnlichem aufteilen. Die genauen Mechanismen, die hierfür verwendet werden sollen, werden wahrscheinlich unter simulierten Belastungen experimentiert. Das Ändern dieser Partitionierungsregel ist ein relativ seltenes Ereignis: Möglicherweise überwacht ein 5- oder 10-Minuten-Timer die Serverlast und versucht, eine optimalere Aufteilung zu ermitteln.
  • Es ist zulässig, dass ein Serverhost ein Datenbankserver (Cluster), ein Spielelogikserver oder (für Clustergröße = 1 System) beides ist. Es ist eine Selbstverständlichkeit, dass wir DB-Instanzen unter der Kontrolle des Hauptplanersystems hochfahren und auf beliebig komplexe Weise konfigurieren können, um den Beitritt zum Cluster zu verwalten und so weiter. Möglicherweise kann dies das Erstellen zugrunde liegender RAM-Discs oder Partitionierungsregeln usw. umfassen.
  • Daher kann der Datensatz für einen bestimmten Host eine Kombination aus einem bestimmten Satz von Tabellen (Komponenten) sein, ist jedoch nur an einem bestimmten Pool von Entitäten interessiert, die nach einem separaten Kriterium ausgewählt wurden. Aus Gründen der Effizienz können wir entweder eine Spalte in der entitiesTabelle speichern, die angibt, zu welchem ​​„Serverlokalitätspool“ sie gehört, oder eine separate Tabelle, die diese Zuordnung bereitstellt, oder etwas in diesem Sinne.
  • Es gibt eine angeborene Annahme, dass die einzelnen Datensätze ausreichend Daten enthalten, um die Integrität aufrechtzuerhalten, solange das Back-End-Datenbankjournal nicht zerstört wird. IE: Solange eine Transaktion stattfindet COMMIT, ist es uns angesichts eines Absturzes nicht sonderlich wichtig, ob wir das Vorher- oder Nachher-Image einer bestimmten Transaktion erhalten. Ich glaube, ich habe dieses Konzept verbal entstellt: Anders ausgedrückt, wir sind zum Zwecke der Crash-Wiederherstellung nicht sonderlich besorgt darüber, ob ganze Transaktionen verloren gehen, solange wir ganze Transaktionen verlieren. Die Möglichkeit, einen Cluster-Host zu verlieren (z. B. Maschine fängt Feuer), wird auf Planerebene behandelt, und der Verantwortungsbereich dieses Hosts kann relativ schnell neu zugewiesen werden, wenn wir einen Herzschlagverlust feststellen.
  • Fast jeder Host schreibt ungefähr halb so viel wie er liest, was viel höher ist, als viele Datenbanksysteme erwarten.

Übersicht (TL; DR)

Wir haben eine Menge Linux-Boxen mit PostgreSQL. Wir haben einige Funktionen, die eine Teilmenge von Daten aufnehmen, die mithilfe eines SELECToder VIEWauf diesen Hosts ausgeführt werden können, und Änderungen fast so oft ausschreiben, wie sie gelesen werden.

Reines theoretisches Modell

Hier wird es schuppig:

Die Komponenten werden direkt relationalen Tabellen und Zeilen zugeordnet. Angenommen, es gibt eine Positionskomponente. Die Entitäts-ID wäre ein Primärschlüssel in einer Tabelle und zur Konsistenzprüfung auch ein Fremdschlüssel für eine entitiesTabelle, die nur ein PK- SERIAL8Feld enthält. Die Positionstabelle enthält dann beispielsweise x NUMERIC, y NUMERIC, z NUMERICSpalten.

Stellen Sie sich dann ein System für die Schwerkraft vor, das Positions-, Massen- und Trägheitskomponenten benötigt, und ein anderes System für Kollisionen, das diese Komponenten sowie eine PhysicalVolume-Komponente verwendet.

In einer perfekten Welt (dh Leistung spielt keine Rolle) wissen wir, welche Entitäten von einem System unter Verwendung eines SQL SELECTmit einigen Kriterien angesprochen werden . Möglicherweise verfügt das PhysicalVolume über einen Begrenzungsrahmen, der das schnelle Ausmerzen von Entitäten ermöglicht, die entweder kein physisches Volume belegen oder sich eindeutig nicht in der Nähe einer anderen Entität befinden, mit der sie möglicherweise kollidieren (einige, die nicht allzu ausgefallen JOINfür Position und PhysicalVolume sind) ). Wir haben also eine Systemdefinition, die auflistet: Welche Komponenten, von denen Daten benötigt werden, und eine SELECTAbfrage, um diese als unveränderliche Datensatzstruktur zu einem bestimmten Zeitpunkt zu erhalten. Diese Datensätze werden einzeln in die Systeme eingespeistrunFunktion, und es führt alle erforderlichen Änderungen. Wenn das System in eine Komponente schreibt, die es nicht liest, wird dies im Voraus deklariert, um die Datenlokalität zu erhalten.

Die Realität setzt ein

Das Problem ist natürlich, dass SQLs SELECTvon Remote-Discs nicht die Art von Dingen sind, die man in jedem „Frame“ einer Hauptsimulationsschleife ausführen möchte. Einige dieser Systeme laufen möglicherweise über 10 Hz.

Jetzt weiß ich, "keine Optimierung vor seiner Zeit", aber dies scheint ein "zum Scheitern verurteilt" -Modell zu sein, es sei denn, es gibt eine Möglichkeit, dieses theoretische Modell in Echtzeit zu verwenden.

Als weitere, notwendige Option für größere Installationen möchte das Planersystem möglicherweise auch "Pools" von Entitäten, höchstwahrscheinlich solche, die sich "physisch" in einer bestimmten Region der Spielwelt befinden, auf einzelne Hosts migrieren, um dies auszugleichen Laden und halten Sie die "Cache-Fehler", die eine allgemeine Back-End-Datenbank treffen müssen, relativ niedrig.

Die Frage (endlich!)

Gegeben

  • ein Datenpool für
    • eine Reihe von VIEWs und aktualisierbaren VIEWs
    • … Die Eingangsquellen und Ausgangssenken bereitstellen für:
      • eine bestimmte Reihe von Systemen
      • (dargestellt als Liste von Tabellen)
      • … Wie auf einen aufgezählten Pool von Entitäten angewendet,
      • (dargestellt als nicht zusammenhängende Auswahl von SERIAL8 REFERENCEs)

… Gibt es einen vernünftigen Weg zu schaffen

  • eine In-RAM-PostgreSQL-Instanz (oder ähnlich)
    • … Die die Hauptautorität für die angegebenen Daten beibehält…
  • ohne die allgemeine Transaktionsintegrität zu brechen?

Wenn dies ein unvernünftiger Entwurf ist, besteht mein Fallback-Konzept darin, im Wesentlichen den gleichen Effekt zu simulieren, indem ich versuche, die Ansichten in temporäre In-RAM-Tabellen oder ähnliches vorzuladen, obwohl ich nicht viel Zeit damit verbracht habe, darüber nachzudenken, wie schlecht das funktionieren könnte.

Jede plausible Alternative, die dem zugrunde liegenden theoretischen Modell dienen könnte, wird geschätzt.


Das kriegsharte Datenbankdesign sollte sowohl für die gesamte Ansicht als auch für einige knifflige Details berücksichtigt werden. Ich empfehle das Buch " The Art of SQL ". Ich neige zu Ihrer Besorgnis über die Datenbank, und die "keine Optimierung vor ihrer Zeit" ist beim Datenbankdesign nicht der Fall. Die ersten beiden Kapitel des Buches sollen Ihnen einen klareren Überblick über Ihr Problem geben. Es tut mir leid, dass ich Ihnen keinen nützlicheren Vorschlag machen kann.
Mike Lue

Fragen Sie nach einer einzelnen Postgres-Instanz, die im Speicher ausgeführt wird, oder stellen Sie die Frage zum Clustering?
Jack sagt, versuchen Sie topanswers.xyz

Ein bisschen Clustering, denke ich. In seiner einfachsten Form ein RAM-Cluster-Mitglied (auf jedem "verarbeitenden" Host), das eine Teilmenge eines Clusters von einem oder mehreren Disc-Backed-Servern spiegelt ...?
BRPocock

Antworten:


3

Das ist eine lange Frage.

Zunächst einmal ist mein aktuelles Projekt (ich bin der Datenbank-Typ, es gibt MMO-Engine-Experten, die sich damit befassen) eine Form von MMORPG, die auf einer Standard-Engine basiert. Volumes wären wie Eve Online- oder "World of Tanks" -Bände.

Nun zu einer orthogonalen kurzen Antwort:

  • DB und Engine vollständig trennen
    Aufgrund von Hardwareoptimierungen nicht mischen und anpassen
  • Hardware: DB und Motor - Server werden Art und Weise unterschiedliche Spezifikationen
  • Entwerfen Sie Ihre Datenbank normal

Es gibt natürlich noch viel mehr, aber ich würde vorschlagen, dass Sie das Problem überdenken und sich in den Fuß schießen. Ich wende einfach die gleichen Techniken auf mein MMO an, die ich im Investment Banking verwendet habe, da IMO die meisten Systeme mit hohem Volumen zu einer ähnlichen Architektur konvergieren sollten

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.