Synchron oder Asynchron, Blocking oder Non-Blocking

Seit geraumer Zeit, ungefähr ein dreiviertel Jahr, beschäftige ich mich mit verschiedenen Art und weisen Anfragen von Benutzern zu beantworten. Die Ursprüngliche Zielsetzung dabei, war für ein Schulnetzwerk einen möglichst kostengünstigen Server mit minimaler Hardware (quasi ein altes Schrott Teil was noch irgendwo rumsteht und keiner mehr haben will) hinzustellen und dabei trotzdem schnell auf Anfragen zu antworten. Nach etwas recherche bin ich auf node.js und die passenden Vorträge dazu gestoßen.

Schon eher stolperte ich ab und an über Asynchrone Ein- und Ausgabe aber wurde mir deren Bedeutung kaum bewusst. Aber immer mehr drängt sich bei mir ein Gedanke auf: Warum um Himmels Willen hat das bisher nicht eigentlich jeder schon gemacht?

Die Vorteile sind eindeutig. Aber zu erst zur Art und Weise. Bisher, bei Synchroner Ein und Ausgabe, war es so, dass Programmcode ausgeführt wurde und wann immer eine Ein- oder Ausgabe stattfand, hielt das Programm an und lief erst nach Beendigung dieser weiter. So wurde unnütz Zeit verschwendet, weil immer gewartet wurde und dann erst weiter gerechnet. Beim Asynchronen Zugriff ist es jedoch so, dass die Ein-/Ausgabe gestartet wird und das Programm erstmal weiterläuft bis eine Meldung zurück kommt, dass diese nun fertig ist.

Am Beispiel eines HTTP Webservers. Bisher: Es kommen 10 Nutzer und wollen 10 Dateien holen. Der erste sendet seine Anfrage und der Server fängt an zu rattern um die gewünschte Datei zu holen. Während dessen kommen die nächsten 3 Nutzer und wollen eine Anfrage stellen. Diese werden erstmal auf einen Stapel gelegt und zum Warten befohlen. Ist der Server nun fertig und hat die Datei gelesen schaut er ob der User nun bereit ist die Daten in Empfang zu nehmen. Wenn nicht wartet nun der Server bis der User bereit ist und sendet ihm nun die Daten. Im schlimmsten Fall ist der User gar nicht mehr da, das Warten war umsonst und nach einer gewissen Zeit (Timeout) wirft der Server die Anfrage weg. Ist er noch da sendet der Server und schließt die Verbindung. Nun nimmt er sich den nächsten user vom Stapel und holt dessen Anfrage (auch darauf wird gewartet). Auch hier kann es wieder zum Timeout kommen. Wenn nicht fängt das Spiel (siehe Absatzanfang) wieder von vorn an.

Ein erster Lösungsansatz, der sich auch lang gehalten hat war und ist, mehrere Stränge (Threads) aufzumachen, die quasi parallel mehrere Anfragen bearbeiten können. Dies führt aber nach und nach zu einem immensen Speicher- und Ressource verbrauch.

Also nun zur asynchronen Variante. Dafür ist eine Methode die “Event Loop“. Dabei beginnt der Server nichts zu tun und eine Schleife zu laufen bis ein Benutzer sich verbindet. Tut er das meldet der Server zurück das er los senden kann und fällt zurück in seine Schleife. In dieser Zeit können sich noch mehr Benutzer verbinden. Ist nun einer soweit und hat die komplette Anfrage nach einer Datei gesendet, nimmt der Server diese auf und startet den Dateilesevorgang. Wieder fällt er in seine Schleife zurück. während die Datei gelesen wird, kann der Server weiter Anfragen entgegen nehmen und weitere Lesevorgänge starten. Ist nun eine Lesevorgang fertig, und der zugehörige Nutzer bereit zum datenempfangen sendet der Server. Ist die Datei fertig der Nutzer aber nicht zum empfangen bereit, bleibt die Datei im Zwishenspeicher und der Server arbeitet solange weiter und leitet gerade genannte Vorgänge ein bis entweder der Timeout erreicht ist und er die Daten wegwirft oder der Nutzer bereit ist und er die Daten senden kann.

Die Vorteile dessen liegen auf der Hand. Einerseits werden viel weniger Ressourcen benötigt, da keine zusätzlichen Threads aufgemacht werden, sondern der Server in (quasi) einem einzigen Thread läuft. Weiter stören Anfragen die ins Leere gehen den Server nicht mehr, da er ja auch nicht mehr wartet. Er wirft die Daten lediglich irgendwann weg. Außerdem können viel mehr Anfragen schnell bearbeitet werden, da alle immer zum Best möglichen Zeitpunkt weiterverarbeitet werden, nämlich immer dann wenn Daten und Empfänger bereit sind, und nicht schon gewartet und geschaut wird obwohl der User noch gar nicht bereit ist.

Ich für meinen Teil bin davon überzeugt, dass Asynchrone I/O sowie Asynchrone Server die kommende Technik sind. Auch wenn Hardwarehersteller sicher sehr dagegen sein werden. Aber die Finanziellen und die Ressourceneinsparungen sind enorm. Auch die Möglichkeiten sind sehr breit gestreut. Eines meiner Projekte beschäftigt sich eben damit und ich versuche dabei einen kleinen, schnellen, asynchronen Server mit der auf allen UNIX(oiden) Systelem vertretenen Sprache Python zu realisieren. Und die bisherigen Ergebnisse sind doch schon erstaunlich. Aber später mehr davon.

Mal wieder ist es ein sehr langer Eintrag geworden und es ist noch immer nicht alles gesagt. Es wird sicher auch nicht der letzte zu diesem Thema bleiben.

Leave a comment

0 Comments.

Leave a Reply


[ Ctrl + Enter ]