Server Archetektur und ICP

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Xbash_Zero
User
Beiträge: 30
Registriert: Montag 19. September 2022, 22:48

Hallo,

ich bitte Euch um Rat und Tipps zu einem Thema, an welchem ich jetzt schon seit einiger Zeit am Recherchieren bin. Es geht darum, ein performantes Backend zu designen, die Architektur zu optimieren und später evtl. zu entwickeln. Da es so viele Möglichkeiten gibt dies zu tun, möchte ich versuchen meine Frage etwas zu spezifizieren und meine bisherigen Überlegungen aufzeigen:

Mein Ansatz sieht wie folgt aus, dabei soll zunächst eine horizontale Skalierung vernachlässigt sein. Ich teile die Server Anwendung in verschiedene Prozesse auf:

Socket_Handling_Process (Zustandsbasiert bzgl. der Verbindungen - Sende/Empfangen von Nachrichten via TCP)
Message_Handling_Process (Zustandslos, die Nachrichten sollen nur vermittelt werden)
Caching_Handling_Process (Zustandsbasiert bzgl. der Anwendungszustände)
Database_Handlin_Process (Datenbank I/O, Schreiben, Lesen in die Datenbank)
.
.
Other_Processes (Dies könnten andere Prozesse sein, welche Aufgaben, Berechnungen usw. erledigen oder eine Schnittstelle zu anderer Software bereitstellen)


Kurze Erklärung, warum ich die Aufteilung zu Prozessen mache und nicht alles in einer asynchronen Implementierung mittels asyncio:

1. Auch wenn eigentlich asyncio für I/O Bound der primäre Ansatz ist, so denke ich mir, könnte später evtl. über Message Queues oder Channel (Redis) skaliert werden, je nachdem wie hoch die Kosten der Synchronisation sind, falls diese notwendig werden sollte (Zustände usw.).
2. Eine moderne CPU hat mehrere Kerne, die ich gerne nutzen möchte.


Innerhalb mancher Prozesse könnten asynchrone Tasks bzw. eigenständige Event_Loops laufen, falls dies sinnvoll ist, zB. bei den Socket Verbindungen. Ich bin mir gerade nicht sicher, wie das Pythonmodul "sockets", low level technisch implementiert ist, also selectors/epoll ... müsste ich nachsehen ... Worauf ich aber hinaus möchte ist, dass es durchaus Sinn ergeben könnte, wenn innerhalb des Socket_Handling_Processes, das Empfangen und Senden asynchron erfolgt. Also in meinem Konzept sieht das dann so aus, dass Nachrichten empfangen und diese in eine Queue gespeichert werden, andersherum beim Versenden. Ich glaube auch, dass dies ein Vorteil ist, weil die Daten dann, je nachdem wann diese vom Socket empfangen wurden, gleich in der richtigen Reihenfolge serialisiert werden und man braucht sich auch keine weiteren Gedanken über die Synchronisation der Daten zwischen den Prozessen zu machen.


Nun zu meinen Fragen:

- Wie beurteilt ihr diese Architektur, gibt es Verbesserungsvorschläge?
- Würdet Ihr Multiprocessing und AsyncIO kombinieren, wenn dies Sinn macht? Würde dies in meinem Szenario sinnvoll sein?
- Welche Technik sollte man für die Interprocess Kommunikation verwenden? Qeues, Redis, Kafka ... Wobei Redis eher Subscriber/Publisher Channels sind und diese können auch für IPC verwendet werden, das habe ich mal getestet, allerdings habe ich keine Benchmarks gemacht. Bei den Queues könnte man zum Beispiel q.put(var, non_blocking) verwenden, das wäre dann mit asyncio kompatibel.


Ich hoffe, hier kann mir weiter geholfen werden, bitte beachtet, dass es sich hier mehr um ein hypothetisches Konzept handelt, wobei ich versuche mein Verständnis etwas weiter auszubauen.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Mir ist der Zweck des Ganzen noch nicht klar. Man konstruiert ja keine komplizierte Architektur nur um der Architektur willen. Was ist das Ziel, das Du erreichen willst?
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du zäumst das Pferd komplett von hinten auf. Dieses theoretische fabulieren ohne einen konkreten Anwendungskontext ist Quatsch mit Soße. Du wirst nicht die eine Architektur sie alle zu Knechten finden, wenn’s sowas gäbe, wäre das schon in Form eines Frameworks gegossen. Stattdessen baust du eine tatsächliche Anwendung, und wenn die an ihre Grenzen kommt, schaust du dir genau an, was die sind, warum die sind, und triffst daran Entscheidungen.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

hast du schon mal irgendwas bestehendes probiert und bist an eine Grenze gestoßen? Wenn ja was und welche?
Qeues, Redis, Kafka ...
Das deckt das volle Spektrum von e wie einfach bis mk wie mega-komplex. Mit Queues und bis zu einem gewissen Grad auch Redis kannst du auch auf schwachbrüstigen Rechnern arbeiten, Kafka braucht AFAIK einen Servercluster und ist auf hochvolumiges, hochfrequentes Messaging ausgelegt. Du musst du schon wissen, was du wirklich brauchst, weil das eine ist kein Ersatz für das andere...

Und "perfomantes Backend" ist auch relativ und mehrdimensional. Software Performances kann man bis zu einem Gewissen Grad mit Hardwareperformance ausgleichen. Und umgekehrt.

Gruß, noisefloor
Xbash_Zero
User
Beiträge: 30
Registriert: Montag 19. September 2022, 22:48

Ok, ich denke, ich verstehe das, danke für die Hinweise!

Im Moment habe ich auch keine Anwendung, welche meine Überlegungen bzgl. der Performanceoptimierung nur ansatzweise ausreizen würde und ein hohes I/O Aufkommen hätte man unter anderem bei einem hohen User aufkommen, oder wenn irgendwelche Messwerte ständig hin und her gereicht werden müssten für die weitere Berechnung usw. beide Anwendungsfälle sind aktuell noch nicht direkt in der Planung. Ein anderes Vorhaben, was ich schon seit längerem mal machen wollte ist, eine Art Trading Bot zu erstellen. Wenn das Server-Design so geplant wird, dass es modular aufgebaut ist, dann könnte ich es für andere Anwendungsfälle ebenfalls nutzen, durch minimales Umschreiben oder durch Schnittstellenerweiterungen zum Beispiel.

Aber ich denke, ihr habt komplett recht, jede Anwendung ist für sich selbst zu spezifisch, sodass es mehr Sinn ergibt, die Architektur anhand des Anwendungsfalls zu planen und nicht andersherum.
hast du schon mal irgendwas bestehendes probiert und bist an eine Grenze gestoßen? Wenn ja was und welche?
Nur ein wenig herumgespielt, also mit Queues und Redis, aber keine Limits erreicht bis jetzt^^

Und "perfomantes Backend" ist auch relativ und mehrdimensional. Software Performances kann man bis zu einem Gewissen Grad mit Hardwareperformance ausgleichen. Und umgekehrt.
Stimmt, vertikales Skalieren bezieht sich, soweit ich weiß, auf die Hardware, horizontales Skalieren müsste dann so etwas wie Loadbalancing sein, letzteres ist bei zustandsbasierten Implementierungen nicht ganz trivial, wegen der Synchronisation.

Na ja, es waren ja nur theoretische Überlegungen und kein Vorhaben Facebook neu zu erfinden, ich hatte einfach Redebedarf über das Thema, weil es mich auch interessiert und weil ich sonst niemanden hier physikalisch habe, mit dem ich darüber philosophieren kann.

Zu mindestens muss ich mir keine Sorgen machen, dass ich bei meinen Anwendungen auf Engpässe in absehbarer Zeit stoßen werde :-)

Beste Grüße
Xbash
Antworten