High Performance Server

Freexer

Grünschnabel
Hallo,

also ich wollte nen Netzwerk Server schreiben und dieser sollte bis zu 10 000 leute behandeln können, natürlich mit einer dementsprechend starken Hardware.
Da ich aber hier nicht einfach drauf los Programmieren könnt ihr euch sicher denken sondern ich wollte mich erstmal genau informieren mit was ich die Performance bis zum schluss ausnutzen kann.
Der Server muss nichts resourcen lastiges machen es werden halt kleinere Packete geschickt mit Informationen was der Server dann halt verarbeiten muss mit kleineren Algorythmen und halt das Ergebnis an den Client zurück. Die Infos werden in einer Mysql Datenbank gespeichert.

Ich wollte das ganze so machen die Infos dauerthaft im Ram zu behalten und in abständen in nem extra Thread in die DB zu speichern um den Programm fluss nicht aufzuhalten.

Ich habe jetzt schon bei manchen Server Programmen einen Thread Pool gesehen der eine Anzahl von Threads zuverfügungstellt und diese sich dann um die ganzen Tasks die Laufen kümmern.

Ich versteh aber noch nicht ganz wie das ganze funktioniert mit dem Thread Pool bis jetzt habe ich immer die ganzen Normalen Thread benutzt und bei Google finde ich auch nichts informatives was mich richtig weiter bringen könnte villt hat ja jemand von euch ne Seite/Beispiel oder ne genaue erklärung wie so ein Thread Pool funktioniert und auf was ich achten muss.

Jetzt noch zum Netzwerk Code, ich habe ich da auch schon ein bisschen Informiert man könnte ja für jeden zu behandelenen Client einen Thread erstellen aber irgentwann würde das System doch bei so vielen Thread in die Knie gehen.
Nun habe ich gelesen das ich unter linux Epoll benutzen soll das sei sowas ähnliches wie Select sein aber jetz weiß ich nicht wie ich das am besten mit dem Epoll angehen soll, weil mehere 1000 Clients mit Epoll zu behandeln in 1 Thread kann doch auch nciht so gut sein oder kann man irgentwie durch den Thread Pool dafür sorgen das sich mehrere Threads sich um das Epoll kümmern weil ich denke nicht das ich Epoll irgentwie mehrmals benutzen kann in mehren Threads.

:p Ich danke euch schon für euere Hilfe :)
 
Hi,

wenn du nicht für jeden Clienten nen eigenen Thread erstellen willst,
kannst du ja auch z.B. einen Thread 10 oder 100 Verbindungen behandeln lassen.

Dann muss einer schonmal nicht alle Behandeln.

Oder du legst am Anfang fest das es Genau 100 Threads geben soll und dann wird halt immer dem Thread mit den wenigsten Clients ein neuer zugefügt.

Gruß
Anfänger

Edit:
Bist du sicher das Epoll das richtige ist?
Wenn du mit Sockets arbeitest könntest du auch "select" oder so benutzen.
Damit kann man versuchen z.B. Daten zu Empfangen und wenn keine da sind kehrt er auch zurück.
 
Zuletzt bearbeitet:
Vorab gesagt: Ich lese aus deiner Frage, dass du nicht mal die Grundlagen eines Serveraufbaus kennst, und wenn dem so ist, dann macht es wenig Sinn gleich mit "High Performance" anzufangen.

Seis drum, ich versuch mal ein paar Ansätze:

1) Wenn du Userdaten im RAM und zeitversetzt ein Kopie davon in einer MySql Datenbank speichern willst, dann bekommst du heftigste Probleme mit Synchronisation.
Der Zeit- und Rechenaufwand den du dem Server damit aufhalst ist weit höher als alle Performance die du mit einer RAM-DB gewinnen könntest.

2) Ob du den Server in Threads nach Tasks oder nach Users aufteilst bleibt sich effektiv gleich, nur dürfte die Aufteilung nach Tasks um einiges komplizierter sein, weil auch da wieder diverse Probleme mit Synchronisation auftreten.
Jedem User einen eigenen Thread zu geben verliert keine Performance, auch nicht bei 10000 Usern, Threads die nichts zu tun haben brauchen kaum Rechenzeit, vorausgesetzt du baust keine while() Schleifen die 100% CPU Last verursachen.
Mehrere User im selben Thread zu verwalten kostet dich genau so viel Zeit, weil die foreach() Schleife für alle User innerhalb des Thread genausoviel Rechenzeit braucht.

3) Ganz grundsätzlich bieten SOCKETS die beste Performance, alles weitere, wie z.B. Epoll setzt nur darauf auf, sprich ist ein zusätzlicher Layer, der den Code einfacher macht, aber Performance kostet.

4) Wenn du wirklich Performance willst, brauchst du für 10000 User mehr als einen Server, zumindest wenn die alle gleichzeitig verbunden sein sollen.
Überleg mal: Wenn du pro User nur 1KB an Daten verwalten willst, schaufelst du bei 10000 Usern permanent 10MB Daten durch den Speicher.
Nach meiner Erfahrung geht ein Server selbst bei minimalsten Funktionen in die Knie, wenn mehr als 2000 Verbindungen verwaltet werden müssen.
Wenn du ausser der reinen Userverwaltung noch ein bischen an Funktionen einbauen willst, brauchst du in etwa 1 Server pro 500 gleichzeitige Verbindungen.
Wenn du ausserdem noch Libraries wie mysql++ verwendest und vielleicht den traffic noch encoden/decoden willst, landest du bei 1 Server pro 200 Verbindungen.
 
Hi,

Noch mal was zu dem was Thomasio geschrieben hat, da es mich auch interessiert:

Zu Punkt 2:
Bist du sicher das viele Thread den CPU nicht doch stark belasten?
Ich miene wir reden von möglichen 10.000 Tasks.
Wenn der Kernel dann nen Taskwechsel durchführt und die meißten Threads noch auf Antwort warten muss er während des Taskwechsels vll 1000x prüfen ob ein Task weiter arbeiten kann, bevor er einen geeigneten findet.

Zu Punkt 4:
Warum nur 200 User pro Server wenn es viele Funktionen geben soll + DB.
Ich sag nur guck dir die MMORPG Server an, z.B. die Privaten.
Einige private Server laufen wirklich schnell und stabil auch noch bei 500-700 Usern und es sind auch nur "normale" PC's (Dual-Core mit 4 Ghz o.ä. und 4-8 GB-Ram).

Außerdem kann er ja auch als Server z.B. nen Itanium-Server benutzen.
Ich sag nur: (Bis zu 512 Prozessoren, jeder 2GHz und einen überdimensional großen möglichen RAM)

Gruß
Anfänger
 
@Anfänger

1) Natürlich belasten viele Threads die CPU.
Was ich sage ist: Mehr Threads belastet die CPU nicht MEHR als in jedem Thread eine foreach() Schleife für alle User.
Eher im Gegenteil, WENN man einen High-End-Server mit einem Haufen CPU´s hat, dann läuft das eher schneller, weil:

2) Mehrere User in einem Thread verwalten heisst, dieser Thread läuft auf EINEM Kern, selbst wenn der Server 500 CPU´s a 4 Kerne hätte, ein einzelner Thread kann sich nicht auf mehrere Kerne verteilen.
Somit liegt die Performance pro Thread bei max. Signle-Core-Mhz.

3) In jedem Fall braucht man aber eine gute Synchronisation, via mutex oder so, weil jede Änderung an den Daten, ob nun RAM-DB oder MySql, vor gleichzeitigem Zugriff aus anderen Threads geschützt werden muss.
Das bremst bei 2000 Usern absolut alles aus, ob nun QuadCore oder 500 CPU´s.
Je mehr User eingeloggt sind und je mehr Funktionen der Server haben soll, desto mehr bremst die Synchronisation.
In Grenzen kann man durch Optimierung der Synchronisation das Ganze beschleunigen, wenn da echte Profis am Werk sind, kann man auch 500 User flüssig verwalten, aber 2000 User verwalten, ohne dass der Server in die Knie geht, ist auch damit nicht drin.
 
Also erstmal tut mir leid für die Späte antwort habe ich mich weiter informtiert das mit Mutex etc kenn ich schon habe ich auch schon oft damit gearbeitet aber ich wusste nich dass,das ganze Syncronisation heißt, wir sind im moment ein Team aus 5 Leuten die einen mehr die anderne weniger Ahnung haben.

Ich und ein anderer Kollege planen gerade den Server und unser Hauptthema wo wir uns am meisten Gedanken machen ist wenn mehrere Threads gleichzeitig zugreifen sprich Syncronisierung.
So Profi muss man da nicht sein, ist einglich alles eine sache der Überlegung und schauen das es wenig wie möglich eintritt.

Und das mit dem in abständen sichern in der SQL DB sollte doch einglich kein Problem machen ich erstell mehrere DB Verbindung und wenn 1 Client was sichern will wird halt ne freie DB Verbindung genommen und so ensteht keine Verzögerung. DIe Anzahl der DB Verbindungen kann ich ja mit der Anzahl der Benutzer ausrechnen lassen das z.b pro 100 Leute 1 Verbindung da ist oder so.

Was haltet ihr davon nen extra Thread zu machen und dort container erstellen, wo ich die Daten zum Speichern ablege und der Thread arbeitet das dann nach einander ab so muss ich nicht auf eine freie Verbindung warten.

Ja und wir haben wahrscheinlich vor Pro Thread 10-20 User zu verwalten oder ähnliches mit Epoll/Select oder so sollte doch am besten sein ?
 
Zuletzt bearbeitet:
'n Abend!

Sag mal, worum geht's eigentlich genau? Prinzipiell einen speziellen Server zu entwickeln oder plant Ihr eine Applikation die Speed braucht?
Da ich von letzterem ausgehe, kann ich nur raten mal den "neuen" Server zu vergessen...

Ich lese aus deiner Frage, dass du nicht mal die Grundlagen eines Serveraufbaus kennst, und wenn dem so ist, dann macht es wenig Sinn gleich mit "High Performance" anzufangen.
Natürlich belasten viele Threads die CPU.

Schon mal überlegt, auf bewährte Bausteine zurückzugreifen? Z.B. wäre ein lighty + FastCGI ein sehr guter Start wenn's um Performance geht..
Allerdings wirst Du im eigentlichen Programm auf eine Alternative zur reinen libfcgi wohl nicht herum kommen, da Multiplexing, also das "gleichzeitige" Abfertigen von mehreren Clients in einem Thread, standardmäßig nicht unterstützt wird. (Oder hat sich das inzwischen geändert?)
Zum Glück haben sich andere darüber schon den Kopf zerbrochen, ein guter Einstieg ist bestimmt Peter Simons' "FastCGI - The Forgotten Treasure".

Wie auch immer, in jedem Fall ist wohl dringend davon abzuraten, alles von der Pike auf neu zu erfinden. Und selbst wenn Du glaubst das du noch viel, viel mehr Geschwindigkeit 'rausholen kannst ist es besser, bestehende und bewährte Bibliotheken anzupassen als sich ewig mit einem eigenen Fundament und seinen (garantiert auftretenden) Bugs zu befassen. Sagt dir das Not-Invented-Here-Syndrom etwas? ;)

Gruß
Enum
 

Neue Beiträge

Zurück