Hallo zusammen!
Ich würde heute gerne mit euch ein bisschen über einen Teil der Infrastruktur von UW sprechen. Es gibt bei uns nämlich noch deutlich mehr als das, was ihr sehen könnt.
Anfangen werde ich erstmal mit dem Minecraft-Server. Oder eher: Den Minecraft-Servern. Es gibt nämlich eigentlich gar nicht DEN einen Minecraft-Server, sondern nur DIE Server, weil die Welt(en) auf mehrere Server aufgeteilt sind. Jetzt könnte man sich denken: Moment mal, ich wechsel den Server doch gar nicht bei einem Weltenwechsel? Doch. Das tut ihr. Ihr müsst es nur nicht manuell machen, sondern wir übernehmen das für euch. Unsere Server sind alle in einem Netzwerk ('Bungeecord') zusammengeschlossen, welches dann für euch die Aufgabe des Serverwechsels (und noch viel mehr!) übernimmt. Ein besonderes Beispiel hierfür ist unsere Hauptwelt, welche inzwischen tatsächlich auf ganze sechs Server aufgeteilt ist. Serverwechsel sind immer durch "Niemandsländer" erkennbar.
Aber warum das Ganze?
Kurz gesagt: Egal wie stark die Rechenleistung hinter einem Server ist, auf einem Minecraft-Server können nicht mehr als ca. 60 Spieler gleichzeitig online sein, ohne dass mit Leistungseinbußen zu rechnen ist. Seit der 1.13 sind selbst 60 Spieler schon sehr optimistisch. Dies ist auf das Grundgerüst Minecrafts von Mojang zurückzuführen. (Achtung an die Profis: Jetzt kommt eine stark vereinfachte Erklärung) Dieses Grundgerüst sieht vor, dass ein Großteil aller Berechnungen auf einem Prozessorkern (noch genauer sogar nur auf einem Thread) laufen muss. Computerprozessoren haben heutzutage normalerweise so 4 bis 6 Prozessorkerne, welche gleichzeitig arbeiten können. Daraus folgt, dass Minecraft für einen Großteil der Berechnungen (z. B. das Rendern der Welt) nur 25% bzw 16,67% der maximalen Rechenleistung nutzt.
Da die gesamte Spiellogik auf diesem Prinzip basiert, müsste man Minecraft quasi von Grund auf neu schreiben, damit man dieses Problem beheben kann. (Dass Minecraft durchaus performant laufen kann, zeigt die "Minecraft Bedrock Edition", welche nicht in Java, sondern in C++ geschreiben ist.)
Wir haben serverseitig sehr viele Optimierungen vorgenommen, um den Server vor Laggs zu schützen. Leider sind wir durch die Vorgaben sehr eingeschränkt in der Möglichkeiten, den Server zu optimieren.
Kommunikation zwischen den Servern?
Da die Server jederzeit untereinander Informationen austauschen müssen, ist die Kommunikation zwischen ihnen enorm wichtig und muss vor allem extrem schnell vonstatten gehen.
Um sich besser vorstellen zu können, wie das Ganze funktioniert, nehmen wir erstmal ein Beispiel aus dem echten Leben und übertragen es anschließend auf das Servernetzwerk.
Stellt euch vor, ihr heißt Lisa und macht eine Weltreise. Eure Eltern würden jedoch gerne jederzeit wissen, wo ihr gerade seid. Was macht man dann also in Zeiten von WhatsApp und Co.? Richtig! Pakete nach Hause schicken
. Ihr kauft euch nun also regelmäßig Pakete, füllt sie mit tollen Sachen, verschließt sie und schickt sie nach Hause. Eine Postfirma kümmert sich dann darum, dass das Paket dort ankommt, wo es soll. Ist das Paket dann endlich nach 10 Stunden Flug und drei Bahnausfällen zuhause angekommen, können es eure Eltern wieder öffnen, sich den Inhalt anschauen und damit machen, was sie wollen.
Übertragen wir das ganze jetzt auf unser Servernetzwerk, werden die fettgedruckten Aktivitäten auch vom Server ausgeführt. "Lisa" wird zu Server A und "Lisas Eltern" werden zu Server B. Das Paket wird zu einem Datenpaket ('Packet') und die Postfirma wird zu einem Teil der Serversoftware ('Netty'), welche sich um die Datenpakete kümmert. Nehmen wir als Beispiel mal ein Wetterpaket, welches der Spawnserver (die Spawnzone ist ein eigener Server) zu allen anderen Servern der Hauptwelt schickt. Der Spawnserver kümmert sich um das Wetter auf der gesamten Hauptwelt. Er schickt regelmäßig Datenpakete an die anderen Server, in welchen er sie über das aktuelle Wetter informiert. Empfangen die anderen Server ein solches Paket, überprüfen sie, ob das aktuelle Wetter auf dem Server mit dem aus dem Datenpaket übereinstimmt und korrigieren es notfalls. Der Spawnserver muss also ein neues Paket erstellen, in dieses die Wetterinformationen eintragen, es 'verschließen' (für die Profis: In ein Bytearray serialisieren) und dann noch verschicken. Auf diese Art und Weise werden sämtliche Daten zwischen den Servern ausgetauscht. Die Kommunikation zwischen Spielerclient und Server funktioniert auch mit Netty und einem ähnlichen Paketsystem. Wir benutzen jedoch eine eigene Implementierung von Netty für die Kommunikation zwischen den einzelnen Servern.
Eine visuelle Darstellung des ganzen würde in etwa so aussehen (Netty ist ein Framework, welches sich um das Versenden und Verarbeiten von Datenpaketen kümmert. Jede Sekunde werden mehrere Tausend Pakete von Netty verarbeitet. Die Grafik ist nicht ganz aktuell, was die Server angeht):
Es gibt mehrer Arten von Paketen, welche wir verschicken. Das normale Paket hat einen klaren Adressaten und wird auch nur an ihn verschickt. Doch verschicken wir auch Pakete, welche man als "Rundschreiben" ansehen könnte. Diese Pakete haben keinen klaren Adressaten, sondern werden an alle Server verschickt. Desweiteren haben wir die Möglichkeit eine Empfangsbestätigung von anderen Servern zu verlangen, wenn das Paket erfolgreich verarbeitet wurde. Dies geschieht z.B bei Vote-Paketen.
Wo wir gerade schon bei Vote-Paketen sind: Diese werden von unserem selbstgeschrieben Back-End-Server "Boson" an die Minecraftserver verschickt. Neben dieser Aufgabe ist Boson mittlerweile unerlässlich für den Betrieb unseres Servernetzwerkes geworden. @SteuerungC wird euch in den kommenden Tagen in einem eigenen Devblogbeitrag darüber aufklären, was genau ihr euch unter Boson vorstellen könnt.
Wie lange dauert das Verschicken von Packets?
Ich kann euch hier mal reale Werte aus dem Serverbetrieb zeigen. Links stehen die Server, rechts die Datenpaketgeschwindigkeiten ("UP" heißt, der Server kann Pakete empfangen).
Wie man sieht, geht das Ganze wirklich verdammt schnell. Das Erstellen, Befüllen, Verschließen, Verschicken, Empfangen, Öffnen und Verarbeiten dauert normalerweise eine Millisekunde (das ist ein Tausendstel einer Sekunde oder auch 0,001 Sekunden).
Das war es erstmal von mir. Danke fürs Lesen!
Ich würde heute gerne mit euch ein bisschen über einen Teil der Infrastruktur von UW sprechen. Es gibt bei uns nämlich noch deutlich mehr als das, was ihr sehen könnt.
Anfangen werde ich erstmal mit dem Minecraft-Server. Oder eher: Den Minecraft-Servern. Es gibt nämlich eigentlich gar nicht DEN einen Minecraft-Server, sondern nur DIE Server, weil die Welt(en) auf mehrere Server aufgeteilt sind. Jetzt könnte man sich denken: Moment mal, ich wechsel den Server doch gar nicht bei einem Weltenwechsel? Doch. Das tut ihr. Ihr müsst es nur nicht manuell machen, sondern wir übernehmen das für euch. Unsere Server sind alle in einem Netzwerk ('Bungeecord') zusammengeschlossen, welches dann für euch die Aufgabe des Serverwechsels (und noch viel mehr!) übernimmt. Ein besonderes Beispiel hierfür ist unsere Hauptwelt, welche inzwischen tatsächlich auf ganze sechs Server aufgeteilt ist. Serverwechsel sind immer durch "Niemandsländer" erkennbar.
Aber warum das Ganze?
Kurz gesagt: Egal wie stark die Rechenleistung hinter einem Server ist, auf einem Minecraft-Server können nicht mehr als ca. 60 Spieler gleichzeitig online sein, ohne dass mit Leistungseinbußen zu rechnen ist. Seit der 1.13 sind selbst 60 Spieler schon sehr optimistisch. Dies ist auf das Grundgerüst Minecrafts von Mojang zurückzuführen. (Achtung an die Profis: Jetzt kommt eine stark vereinfachte Erklärung) Dieses Grundgerüst sieht vor, dass ein Großteil aller Berechnungen auf einem Prozessorkern (noch genauer sogar nur auf einem Thread) laufen muss. Computerprozessoren haben heutzutage normalerweise so 4 bis 6 Prozessorkerne, welche gleichzeitig arbeiten können. Daraus folgt, dass Minecraft für einen Großteil der Berechnungen (z. B. das Rendern der Welt) nur 25% bzw 16,67% der maximalen Rechenleistung nutzt.
Da die gesamte Spiellogik auf diesem Prinzip basiert, müsste man Minecraft quasi von Grund auf neu schreiben, damit man dieses Problem beheben kann. (Dass Minecraft durchaus performant laufen kann, zeigt die "Minecraft Bedrock Edition", welche nicht in Java, sondern in C++ geschreiben ist.)
Wir haben serverseitig sehr viele Optimierungen vorgenommen, um den Server vor Laggs zu schützen. Leider sind wir durch die Vorgaben sehr eingeschränkt in der Möglichkeiten, den Server zu optimieren.
Kommunikation zwischen den Servern?
Da die Server jederzeit untereinander Informationen austauschen müssen, ist die Kommunikation zwischen ihnen enorm wichtig und muss vor allem extrem schnell vonstatten gehen.
Um sich besser vorstellen zu können, wie das Ganze funktioniert, nehmen wir erstmal ein Beispiel aus dem echten Leben und übertragen es anschließend auf das Servernetzwerk.
Stellt euch vor, ihr heißt Lisa und macht eine Weltreise. Eure Eltern würden jedoch gerne jederzeit wissen, wo ihr gerade seid. Was macht man dann also in Zeiten von WhatsApp und Co.? Richtig! Pakete nach Hause schicken

Übertragen wir das ganze jetzt auf unser Servernetzwerk, werden die fettgedruckten Aktivitäten auch vom Server ausgeführt. "Lisa" wird zu Server A und "Lisas Eltern" werden zu Server B. Das Paket wird zu einem Datenpaket ('Packet') und die Postfirma wird zu einem Teil der Serversoftware ('Netty'), welche sich um die Datenpakete kümmert. Nehmen wir als Beispiel mal ein Wetterpaket, welches der Spawnserver (die Spawnzone ist ein eigener Server) zu allen anderen Servern der Hauptwelt schickt. Der Spawnserver kümmert sich um das Wetter auf der gesamten Hauptwelt. Er schickt regelmäßig Datenpakete an die anderen Server, in welchen er sie über das aktuelle Wetter informiert. Empfangen die anderen Server ein solches Paket, überprüfen sie, ob das aktuelle Wetter auf dem Server mit dem aus dem Datenpaket übereinstimmt und korrigieren es notfalls. Der Spawnserver muss also ein neues Paket erstellen, in dieses die Wetterinformationen eintragen, es 'verschließen' (für die Profis: In ein Bytearray serialisieren) und dann noch verschicken. Auf diese Art und Weise werden sämtliche Daten zwischen den Servern ausgetauscht. Die Kommunikation zwischen Spielerclient und Server funktioniert auch mit Netty und einem ähnlichen Paketsystem. Wir benutzen jedoch eine eigene Implementierung von Netty für die Kommunikation zwischen den einzelnen Servern.
Eine visuelle Darstellung des ganzen würde in etwa so aussehen (Netty ist ein Framework, welches sich um das Versenden und Verarbeiten von Datenpaketen kümmert. Jede Sekunde werden mehrere Tausend Pakete von Netty verarbeitet. Die Grafik ist nicht ganz aktuell, was die Server angeht):

Es gibt mehrer Arten von Paketen, welche wir verschicken. Das normale Paket hat einen klaren Adressaten und wird auch nur an ihn verschickt. Doch verschicken wir auch Pakete, welche man als "Rundschreiben" ansehen könnte. Diese Pakete haben keinen klaren Adressaten, sondern werden an alle Server verschickt. Desweiteren haben wir die Möglichkeit eine Empfangsbestätigung von anderen Servern zu verlangen, wenn das Paket erfolgreich verarbeitet wurde. Dies geschieht z.B bei Vote-Paketen.
Wo wir gerade schon bei Vote-Paketen sind: Diese werden von unserem selbstgeschrieben Back-End-Server "Boson" an die Minecraftserver verschickt. Neben dieser Aufgabe ist Boson mittlerweile unerlässlich für den Betrieb unseres Servernetzwerkes geworden. @SteuerungC wird euch in den kommenden Tagen in einem eigenen Devblogbeitrag darüber aufklären, was genau ihr euch unter Boson vorstellen könnt.
Wie lange dauert das Verschicken von Packets?
Ich kann euch hier mal reale Werte aus dem Serverbetrieb zeigen. Links stehen die Server, rechts die Datenpaketgeschwindigkeiten ("UP" heißt, der Server kann Pakete empfangen).

Wie man sieht, geht das Ganze wirklich verdammt schnell. Das Erstellen, Befüllen, Verschließen, Verschicken, Empfangen, Öffnen und Verarbeiten dauert normalerweise eine Millisekunde (das ist ein Tausendstel einer Sekunde oder auch 0,001 Sekunden).
Das war es erstmal von mir. Danke fürs Lesen!