Fork of Paper, der dem dedizierten Server regionalisiertes Multithreading hinzufügt.
Folia gruppiert benachbarte geladene Brocken, um eine „unabhängige Region“ zu bilden. Genaue Details dazu, wie Folia benachbarte Chunks gruppiert, finden Sie in der PaperMC-Dokumentation. Jede unabhängige Region verfügt über eine eigene Tick-Schleife, die mit der regulären Minecraft-Tickrate (20TPS) getickt wird. Die Tick-Loops werden parallel auf einem Thread-Pool ausgeführt. Es gibt keinen Hauptthread mehr, da jede Region praktisch ihren eigenen „Hauptthread“ hat, der die gesamte Tick-Schleife ausführt.
Für einen Server mit vielen verteilten Spielern erstellt Folia viele verteilte Regionen und kreuzt sie alle parallel in einem Threadpool konfigurierbarer Größe an. Daher sollte Folia für Server wie diesen gut skalierbar sein.
Auch Folia ist ein eigenes Projekt, dieses wird auf absehbare Zeit nicht in Paper aufgehen.
Eine detailliertere, aber abstraktere Übersicht: Projektübersicht.
Servertypen, die die Spieler auf natürliche Weise verteilen, wie Skyblock oder SMP, werden am meisten von Folia profitieren. Der Server sollte auch über eine beträchtliche Spielerzahl verfügen.
Idealerweise mindestens 16 Kerne (keine Threads).
Erstens wird empfohlen, die Welt vorab zu generieren, damit die Anzahl der erforderlichen Chunk-System-Worker-Threads erheblich reduziert wird.
Das Folgende ist eine sehr grobe Schätzung, die auf den Tests basiert, die vor der Veröffentlichung von Folia auf dem von uns ausgeführten Testserver durchgeführt wurden, der etwa 333 Spieler in der Spitze hatte. Es ist also nicht genau und erfordert eine weitere Abstimmung – nehmen Sie es einfach als Ausgangspunkt.
Dabei ist die Gesamtzahl der auf der Maschine verfügbaren Kerne zu berücksichtigen. Weisen Sie dann Threads zu für:
-XX:ConcGCThreads=n
. Verwechseln Sie dieses Flag nicht mit -XX:ParallelGCThreads=n
, da parallele GC-Threads nur ausgeführt werden, wenn die Anwendung durch GC angehalten wird, und daher nicht berücksichtigt werden sollten.Nach all dieser Zuteilung können die verbleibenden Kerne auf dem System bis zu einer Zuteilung von 80 % (insgesamt zugewiesene Threads < 80 % der verfügbaren CPUs) Tickthreads zugewiesen werden (unter globaler Konfiguration, threaded-regions.threads).
Der Grund dafür, dass Sie nicht mehr als 80 % der Kerne zuweisen sollten, liegt darin, dass Plugins oder sogar der Server möglicherweise zusätzliche Threads nutzen, die Sie nicht konfigurieren oder gar vorhersagen können.
Darüber hinaus handelt es sich bei dem oben Gesagten nur um eine grobe Schätzung, die auf der Spielerzahl basiert. Es ist jedoch sehr wahrscheinlich, dass die Thread-Zuteilung nicht ideal ist und Sie sie basierend auf der Nutzung der Threads, die Sie letztendlich sehen, anpassen müssen.
Es gibt keinen Hauptthread mehr. Ich erwarte, dass für jedes einzelne vorhandene Plugin ein gewisses Maß an Modifikation erforderlich ist, damit es in Folia funktioniert. Darüber hinaus führt Multithreading jeglicher Art zu möglichen Race Conditions in den im Plugin gespeicherten Daten – es müssen also zwangsläufig Änderungen vorgenommen werden.
Stellen Sie also eine Kompatibilitätserwartung von 0 ein.
Derzeit gibt es viele APIs, die auf dem Hauptthread basieren. Ich gehe davon aus, dass praktisch keine Plugins, die mit Paper kompatibel sind, auch mit Folia kompatibel sind. Es gibt jedoch Pläne, eine API hinzuzufügen, die die Kompatibilität von Folia-Plugins mit Paper ermöglichen würde.
Zum Beispiel der Bukkit Scheduler. Der Bukkit-Scheduler basiert grundsätzlich auf einem einzigen Hauptthread. Folias RegionScheduler und Folias EntityScheduler ermöglichen die Planung von Aufgaben bis zum „nächsten Tick“ der Region, die entweder einen Standort oder eine Entität „besitzt“. Diese könnten auf normalem Paper implementiert werden, mit der Ausnahme, dass sie für den Haupt-Thread geplant werden. In beiden Fällen erfolgt die Ausführung der Aufgabe in dem Thread, der den Standort oder die Entität „besitzt“. Dieses Konzept gilt allgemein, da das aktuelle Paper (Single-Threaded) als eine riesige „Region“ betrachtet werden kann, die alle Chunks in allen Welten umfasst.
Es ist noch nicht entschieden, ob diese API direkt zu Paper selbst oder zu Paperlib hinzugefügt werden soll.
Erstens macht Folia viele Plugins kaputt. Um Benutzern dabei zu helfen, herauszufinden, welche Plugins funktionieren, werden nur Plugins geladen, die von den Autoren ausdrücklich für die Zusammenarbeit mit Folia gekennzeichnet wurden. Durch Einfügen von „folia-supported: true“ in die Datei „plugin.yml“ des Plugins können Plugin-Autoren ihr Plugin als kompatibel mit regionalisiertem Multithreading markieren.
Die andere wichtige Regel ist, dass die Regionen parallel und nicht gleichzeitig ticken. Sie geben keine Daten weiter, sie erwarten nicht, dass sie Daten weitergeben, und die Weitergabe von Daten führt zu Datenbeschädigung. Code, der in einer Region ausgeführt wird, kann unter keinen Umständen auf Daten in einer anderen Region zugreifen oder diese ändern. Nur weil Multithreading im Namen steckt, heißt das nicht, dass jetzt alles Thread-sicher ist. Tatsächlich wurden nur wenige Dinge threadsicher gemacht, um dies zu ermöglichen. Mit der Zeit wird die Anzahl der Thread-Kontextprüfungen nur noch zunehmen, auch wenn dies mit Leistungseinbußen einhergeht – niemand wird eine Serverplattform verwenden oder dafür entwickeln, die höllisch fehlerhaft ist, und es gibt nur eine Möglichkeit, dies zu verhindern und zu finden Bugs besteht darin, fehlerhafte Zugriffe an der Quelle des fehlerhaften Zugriffs stark zum Scheitern zu bringen.
Das bedeutet, dass Folia-kompatible Plugins APIs wie RegionScheduler und EntityScheduler nutzen müssen, um sicherzustellen, dass ihr Code im richtigen Thread-Kontext ausgeführt wird.
Im Allgemeinen kann man mit Sicherheit davon ausgehen, dass eine Region Blockdaten in etwa 8 Blöcken von der Quelle eines Ereignisses entfernt besitzt (d. h. der Spieler durchbricht den Block und kann wahrscheinlich auf 8 Blöcke um diesen Block herum zugreifen). Dies ist jedoch nicht garantiert – Plugins sollten die kommende Thread-Check-API nutzen, um korrektes Verhalten sicherzustellen.
Die einzige Garantie für Thread-Sicherheit ergibt sich aus der Tatsache, dass eine einzelne Region Daten in bestimmten Blöcken besitzt – und wenn diese Region aktiv ist, hat sie vollen Zugriff auf diese Daten. Bei diesen Daten handelt es sich speziell um Entitäts-/Chunk-/POI-Daten, die keinerlei Bezug zu irgendwelchen Plugin-Daten haben.
Normale Multithreading-Regeln gelten für Daten, die Plugins ihre eigenen Daten oder die eines anderen Plugins speichern/auf sie zugreifen – Ereignisse/Befehle/usw. werden parallel aufgerufen, weil Regionen parallel ticken (wir KÖNNEN sie NICHT synchron aufrufen, da dies zu Deadlock-Problemen führt und die Leistung beeinträchtigen würde). Es gibt keine einfachen Auswege, es kommt allein darauf an, auf welche Daten zugegriffen wird. Manchmal reicht eine gleichzeitige Sammlung (wie ConcurrentHashMap) aus, und oft verbirgt eine nachlässig verwendete gleichzeitige Sammlung nur Threading-Probleme, die dann nahezu unmöglich zu debuggen sind.
Um API-Ergänzungen richtig zu verstehen, lesen Sie bitte die Projektübersicht.
Um API-Ergänzungen richtig zu verstehen, lesen Sie bitte die Projektübersicht.
Allgemeine Faustregeln:
Befehle für Entitäten/Spieler werden in der Region aufgerufen, der die Entität/der Spieler gehört. Konsolenbefehle werden in der globalen Region ausgeführt.
Ereignisse, an denen eine einzelne Entität beteiligt ist (z. B. Spielerpausen/Platzsperren), werden von der Entität, die die Region besitzt, aufgerufen. Ereignisse, die Aktionen an einer Entität beinhalten (z. B. Entitätsschaden), werden in der Region ausgelöst, die die Zielentität besitzt.
Der async-Modifizierer für Ereignisse ist veraltet – alle von Regionen oder der globalen Region ausgelösten Ereignisse gelten als synchron , auch wenn es keinen Hauptthread mehr gibt.
< repository >
< id >papermc</ id >
< url >https://repo.papermc.io/repository/maven-public/</ url >
</ repository >
< dependency >
< groupId >dev.folia</ groupId >
< artifactId >folia-api</ artifactId >
< version >1.20.1-R0.1-SNAPSHOT</ version >
< scope >provided</ scope >
</ dependency >
Die PATCHES-LICENSE-Datei beschreibt die Lizenz für API- und Server-Patches, die in ./patches
und seinen Unterverzeichnissen zu finden sind, sofern nicht anders angegeben.
Der Fork basiert auf dem Fork-Beispiel von PaperMC, das Sie hier finden. Daher enthält es Änderungen daran in diesem Projekt. Lizenzinformationen zu geänderten Dateien finden Sie im Repository.