Akka Antimuster: zu viele Schauspieler

Bild

Von akka gibt es nur wenige Materialien auf Habré. Ich beschloss, einige der von Manuel in seinem Blog beschriebenen Antimuster zu übersetzen. Sie sind für Menschen, die zum ersten Mal auf das Framework gestoßen sind, möglicherweise nicht offensichtlich.

Mir fiel ein, dass ich noch nicht über dieses sehr häufige Anti-Muster geschrieben hatte. Es ist häufig im Code von Entwicklern zu finden, die gerade erst anfangen, mit dem Akteurmodell zu arbeiten.

Es gibt zwei Möglichkeiten, um zu viele Schauspieler zu bekommen:

- ein System mit zu vielen verschiedenen Arten von Akteuren entwickelt haben, von denen viele nicht benötigt werden
- Schaffung einer sehr großen Anzahl von Akteuren zur Laufzeit, wenn dies nicht notwendig und ineffizient ist

Schauen wir uns diese Optionen im Detail an.

Zu viele Arten von Schauspielern


Die allgemeine Idee ist ungefähr so: "Wir haben Schauspieler, also sollte alles ein Schauspieler sein."

Das Akteurmodell vereinfacht das Schreiben asynchroner Anwendungen. Dies geschieht durch die Illusion einer synchronen Codeausführung innerhalb eines Akteurs. Sie müssen sich keine Gedanken über den gleichzeitigen Zugriff auf den Status eines Akteurs machen, da nur ein Akteur auf seinen Status zugreifen kann und Nachrichten nacheinander verarbeitet werden.

Tatsächlich muss jedoch nicht alles asynchron ausgeführt werden. Methodenaufrufe, die ausschließlich der CPU zugeordnet sind (und nicht in dem Sinne „blockiert“ sind, dass sie die CPU nicht vollständig überlasten, z. B. den Pi-Wert berechnen), sollten nicht asynchron ausgeführt werden.

Ich sehe ziemlich oft Code mit einer großen Anzahl verschiedener Akteure, die miteinander interagieren und nichts tun, was einen großen Vorteil bei der asynchronen oder gleichzeitigen Ausführung hat. In diesen Projekten muss jeder dieser Akteure denselben Status speichern oder in jeder Nachricht an sie übertragen.

Dieser Ansatz hat zwei Nachteile:

"Sie bekommen nichts in Bezug auf die Leistung." Im Gegenteil, mit der Erstellung von Nachrichten und ihrer Übertragung ist ein Overhead verbunden.
- Mit jeder Art von Akteur und verwandten Nachrichten wird das System schwieriger zu verstehen und zu warten.

Daher müssen Sie beim Entwerfen von Akteursystemen darüber nachdenken, was eigentlich asynchron sein sollte, im Grunde genommen Folgendes:

- Anrufe an externe Systeme (außerhalb Ihres JVM)
- Aufrufe zum Blockieren von Vorgängen (veraltete APIs, Heavy Computing, ...)

Zu viele Schauspieler zur Laufzeit


Die allgemeine Idee ist ungefähr so: "Je mehr Schauspieler wir haben, desto schneller wird alles gehen."

Tatsächlich sind die Schauspieler leichtgewichtig, und Sie können Millionen von ihnen in einer virtuellen Maschine ausführen . Ja, das kannst du. Aber ist es notwendig?

Bild

Wenn Sie können, heißt das nicht, dass Sie es sollten

Kurze Antwort: nicht immer - es kommt darauf an, was Sie mit den Schauspielern machen.

Wenn Ihr System viele langlebige Akteure hat, von denen jeder einen kleinen Zustand enthält und von Zeit zu Zeit miteinander interagiert, sind Sie möglicherweise mit einer Million Akteuren zusammen - und dies ist ein legitimer Anwendungsfall, der von Akka sehr gut unterstützt wird. Sie können beispielsweise ein System mit einer großen Anzahl von Benutzern erstellen, wobei jeder Benutzer durch einen Akteur dargestellt wird. Ein reiner Akka-Schauspieler benötigt nur 300 Byte Speicher, sodass es durchaus möglich ist, Millionen auf einem Computer zu erstellen und sie arbeiten zu lassen, ohne sich um irgendetwas kümmern zu müssen. Und wenn Sie am Ende viele Schauspieler oder Schauspieler mit einem großen Vermögen erstellen, die nicht mehr in den Speicher einer Maschine passen, vereinfacht Cluster-Sharding die Verteilung der Schauspieler auf mehrere Maschinen.

Wenn Sie jedoch mehrere Arten von Akteuren haben, die an der Berechnung beteiligt sind, z. B. das Parsen eines XML-Dokuments, ist es zweifelhaft, Millionen solcher Akteure zu erstellen (dies spielt keine Rolle direkt oder über einen Router).

Dem Prozessor steht eine feste Anzahl von Kernen (Hardware-Threads) zur Verfügung, und Akka-Akteure verarbeiten Nachrichten in einem ExecutionContext basierend auf einem Thread-Pool. Standardmäßig ist dies ein Fork-Join-Executor, der auf ForkJoinPool basiert und in Java 7 hinzugefügt wurde.

Trotz seines technischen Vorteils ist Forkjoinpool keine Magie, die die Gesetze der Physik aufhebt. Wenn Sie eine Million Akteure haben, von denen jeder ein XML-Dokument (das bereits in den Speicher geladen wurde) und 4 Hardware-Threads analysiert, funktioniert das System nicht viel besser als wenn Sie nur 4 Akteure hatten, die diese XML-Dokumente analysieren (wann) homogener Lastzustand). Tatsächlich funktioniert Ihr System mit 4 Akteuren viel besser, da der Aufwand für Planung und Speicherverwaltung nur minimal ist. Übrigens, wenn Ihr System nur wenige Akteure hat, überprüfen Sie Ihren Thread-Pool, der wahrscheinlich versucht, denselben Thread für denselben Akteur wiederzuverwenden.

Im Allgemeinen funktioniert das System nicht schneller, wenn Sie viele Akteure erstellen.

Staatenlose Schauspieler


Akteure sind objektorientiert (im Gegensatz zu beispielsweise Objekten in Java): Ihr Status ist von außen nicht sichtbar und sie kommunizieren über Nachrichten. Es ist unmöglich, die Kapselung zu brechen, da Sie den Zustand des Schauspielers während seiner Arbeit nicht untersuchen können. Dies ist der springende Punkt bei Schauspielern: Sie bieten Ihnen die Illusion eines sicheren Raums, in dem Nachrichten nacheinander nacheinander ausgeführt werden, sodass Sie einen veränderlichen Zustand in Ihrem Schauspieler verwenden können, ohne sich um die Rennbedingungen sorgen zu müssen (Rennbedingungen - ca. Per.) (Na ja, fast ohne sich Sorgen zu machen: Die Hauptsache ist, den Staat nicht auslaufen zu lassen).

Deshalb ist der Einsatz von Akteuren, die keinen Staat haben, gelinde gesagt etwas seltsam. Mit Ausnahme von Akteuren, die die Beobachtung großer Teile der Hierarchie des Akteursystems steuern (z. B. das Einrichten von Backup-Supervisoren), sind Akteure wirklich darauf ausgelegt, mit langen Berechnungen zu arbeiten, die einen Status haben. Wenn ich lange spreche, meine ich, dass der Schauspieler im Laufe seines Lebens mehrere Nachrichten verarbeitet und je nach Zustand unterschiedliche Ergebnisse erzielt, im Gegensatz zu einmaligen Berechnungen. Für sie sind Futures eine großartige Abstraktion: Sie ermöglichen die asynchrone Codeausführung, ideal für die Arbeit mit einem Netzwerk oder festplattenbezogenen Computern (oder wirklich intensiven Prozessoraufgaben), können zusammengesetzt werden und verfügen über einen Fehlerverarbeitungsmechanismus. Sie lassen sich auch gut in Akka-Schauspieler integrieren (unter Verwendung des Pfeifenmusters).

Im Allgemeinen: Verwenden Sie keine Schauspieler, wenn Sie keinen Staat haben - sie sind nicht dafür vorgesehen.

Source: https://habr.com/ru/post/de420639/


All Articles