Warum ist Akka gut für Parallelität?

9

Ich bin neu bei Akka und dem Schauspieler-Framework. Ich bin mir sicher, dass mir etwas Offensichtliches fehlt. Bitte nehmen Sie meine Entschuldigung im Voraus an.

Ich lese immer wieder, dass einer der Hauptpunkte bei der Wahl von Akka die Art und Weise ist, wie Parallelität verwaltet wird.

Mir ist nicht klar, warum Akka so besonders ist; Ich verstehe, dass es viele kleine Schauspieler gibt, die sehr leicht und schnell sind; Wie kann mir dies jedoch helfen, wenn zwei Benutzer gleichzeitig ein Formular speichern?

Würde ich nicht immer noch eine Art Parallelitätssperre benötigen (pessimistisch / optimistisch / etc ..)?

abx78
quelle
Fragen Sie sich, warum Schauspieler für Parallelität oder speziell für Akka gut sind?
Scriptin
Wouldn't I still need some sort of concurrency lock (pessimistic/optimistic/etc..)?- Ja, aber das liegt in der Verantwortung des zugrunde liegenden RDBMS, nicht des Akteurs. Sehr wahrscheinlich spricht der Akka-Schauspieler nicht direkt mit Ihrem Benutzer. Vielmehr interagieren sowohl der Akka-Akteur als auch der Benutzer (im Wesentlichen ein anderer Akteur) direkt mit der Datenbank.
Robert Harvey

Antworten:

7

Einer der Vorteile von Nachrichtenverarbeitungsmodellen wie Akteuren und Agenten besteht darin, dass die traditionellen Parallelitätsprobleme (hauptsächlich die Synchronisierung des gemeinsam genutzten Status) kein Problem mehr darstellen. Der Schauspieler kann den privaten Status beibehalten und ihn ohne Sperren frei aktualisieren. Das Akteur-Framework stellt sicher, dass jeweils nur eine Nachricht verarbeitet wird. Bei der serialisierten Verarbeitung kann Code sperrenfrei geschrieben werden.

In Ihrem Beispiel für Benutzer, die ein Formular speichern, kann der Akteur die Liste ohne Sperren aktualisieren, vorausgesetzt, der Akteur hat eine Liste einiger Daten aus jedem Formular geführt, da das Framework garantiert, dass jeweils nur ein Formular verarbeitet wird. Traditionell müssten Sie die Listenzugriffe sperren oder eine gleichzeitige Liste verwenden.

Die Parallelitätsstrategie ist eine etwas andere Angelegenheit und liegt immer noch in Ihrer Verantwortung (wobei keine Strategie die häufigste Strategie ist). Um Ihr Beispiel geringfügig zu ändern, nehmen wir an, dass beide Benutzer gleichzeitig versuchen, die gleiche Formularinstanz zu aktualisieren. Ohne Parallelitätsstrategie überschreiben die Änderungen des einen den anderen (wahrscheinlich gewinnt der letzte). Das ist in Ordnung, aber bestenfalls führt dies zu unerwartetem Verhalten für den Benutzer, dessen Änderungen überschrieben wurden. Wenn sie das gerade geänderte Formular anzeigen, hat es unerwartete Werte (vom anderen Benutzer). Im schlimmsten Fall (wenn es sich nicht nur um Formularaktualisierungen handelt, sondern auch um Versandaufträge) kann dies zu Verlusten verschiedener Art (Zeit, Umsatz usw.) führen.

Die Verwendung einer Parallelitätsstrategie hilft, diese Fälle zu identifizieren und sie basierend auf Geschäftsregeln zu lösen. Bei Optimistic Concurrency sendet der Benutzer beispielsweise die Version des Formulars, das aktualisiert wird. Wenn der Akteur die Änderung verarbeitet, stellt er fest, dass der zweite Benutzer glaubt, Version 5 zu aktualisieren, wenn sich das Formular aufgrund der Aktualisierung des ersten Benutzers tatsächlich in Version 6 befindet. Jetzt können wir zumindest den 2. Benutzer darüber informieren, dass sich das Formular bereits geändert hat, seit er mit der Bearbeitung begonnen hat. Oder welche Regeln das Unternehmen dort durchsetzen will.

Wenn Sie ein Formular aktualisieren, ist Ihnen die Parallelität wahrscheinlich weniger wichtig (hängt davon ab, denke ich). In anderen Fällen kann es jedoch sehr wichtig sein, Verstöße zumindest zu überprüfen und zu behandeln. Möglicherweise möchten Sie die Verletzung der Parallelität sogar ignorieren, z. B. wenn die Benutzer verschiedene Abschnitte geändert haben (um die Formularanalogie fortzusetzen). Oder wenn die Änderung große Auswirkungen auf das Unternehmen hat (ein Großauftrag), möchten Sie sie akzeptieren und kleinere Konflikte später lösen (z. B. wurde die jährliche Aktualisierung der Kontaktinformationen noch nicht abgeschlossen).

Ich glaube, Akka hat eine Reihe anderer Dimensionen, wie z. B. den Umgang mit Fehlern, Supervisoren usw., die für Entwickler wichtige Überlegungen sind.

Kasey Speakman
quelle
9

Ich werde über das Akteurmodell im Allgemeinen (nicht nur Akka) im Vergleich zu anderen Parallelitätsmodellen wie der klassischen sperrenbasierten Parallelität und dem ordentlichen Transaktionsspeicher schreiben.

Vorteile

  1. Einfacheres Konzept zu verstehen und zu verwenden

    • Sperrenbasierte Parallelität ist schwierig. Insbesondere ist es sehr schwierig, es richtig zu machen, da es viele Konzepte gibt, die verstanden und verwendet werden müssen, um korrekt und effizient zu sein: Sperren, Semaphoren, Threads, Synchronisation, gegenseitiger Ausschluss, Speicherbarriere usw.

    • Schauspieler hingegen sind ein abstrakteres Konzept; Sie haben Schauspieler, die Nachrichten senden und empfangen. Es ist nicht erforderlich, Konzepte auf niedriger Ebene wie die Speicherbarriere zu erfassen und zu verwenden.

  2. Erzwingt Unveränderlichkeit

    • Mutabilität ist eine Quelle für viele Fehler und Fehler bei der Programmierung, insbesondere in Multithread-Anwendungen. Das Akteurmodell löst dieses Problem, indem es die Unveränderlichkeit erzwingt.
  3. Weniger fehleranfällig

    • Aus den beiden oben genannten Gründen
  4. Effizient

    • Nicht so effizient wie gut geschriebene Sperren, aber im Allgemeinen effizienter als Software-Transaktionsspeicher.
  5. Leicht skalierbar

    • Zumindest theoretisch sollte die Anwendung ziemlich gut skaliert werden, indem mehr Akteure hinzugefügt werden, um Ihre Aufgaben auszuführen. Mit lock-based ist es ziemlich schwierig zu skalieren.

Nachteile

  1. Nicht alle Sprachen erzwingen leicht Unveränderlichkeit;

    • Erlang, die Sprache, in der zuerst Schauspieler populär gemacht wurden, hat im Kern Unveränderlichkeit, aber Java und Scala (eigentlich die JVM) erzwingen keine Unveränderlichkeit.
  2. Immer noch ziemlich komplex

    • Akteure basieren auf einem asynchronen Programmiermodell, das nicht in allen Szenarien so einfach und einfach zu modellieren ist. Es ist besonders schwierig, mit Fehlern und Fehlerszenarien umzugehen.
  3. Verhindert nicht Deadlock oder Hunger

    • Zwei Akteure können sich in dem Zustand befinden, in dem die Nachricht aufeinander wartet. Sie haben also einen Deadlock wie bei Sperren, obwohl das Debuggen viel einfacher ist. Mit dem Transaktionsspeicher sind Sie jedoch garantiert Deadlock-frei.
  4. Nicht so effizient

    • Aufgrund der erzwungenen Unveränderlichkeit und weil viele Akteure denselben Thread verwenden müssen, sind die Akteure nicht so effizient wie die sperrenbasierte Parallelität.

Fazit

Sperrenbasierte Parallelität ist am effizientesten, aber schwer zu programmieren und fehleranfällig. Der Transaktionsspeicher von Software ist am klarsten, am einfachsten zu programmieren und weniger fehleranfällig, aber auch am wenigsten effizient. Zwischen diesen beiden Modellen liegen Akteure mit allen Aspekten: einfache Programmierung, Effizienz und Fehleranfälligkeit.

m3th0dman
quelle
Sollte das für Ihren Vorteil Nummer 2 nicht " Veränderlichkeit ist eine Quelle vieler Fehler ..." und "... löst dieses Problem, indem die Veränderlichkeit verboten wird " statt " Unveränderlichkeit " sein? Der zweite Satz enthält zwei überflüssige Erwähnungen zur Lösung des Problems.
8bittree
@ 8bittree Ja, du bist richtig; Ich habe mich verschrieben. Nur für den Fall, dass Sie es nicht wissen, können Sie die Antworten bearbeiten, um solche Probleme zu beheben.
m3th0dman
Ich bin mir dessen bewusst, ich zögere nur, Änderungen vorzunehmen, die die Bedeutung von etwas umkehren oder drastisch ändern, falls es ein Missverständnis meinerseits ist.
8bittree
Können Sie näher auf Deadlocking eingehen? Es scheint, als müsste man ein sehr umständliches Schauspieler-Setup (bidirektionale Kommunikation) erstellen, um darauf zu stoßen. Wenn Sie ein Muster im Ask-Stil verwenden (A bittet B um Antwort, B verarbeitet die Anfrage und antwortet dem Absender der Anfrage, kontaktiert A jedoch nie direkt). Ich sehe nicht, wie ein Deadlock möglich ist
Daenyth
1
@Daenyth Ich stimme zu, dass Sie ein seltsames Konstrukt verwenden müssten, um einen Deadlock mit Schauspielern zu erreichen. Aus einer ähnlichen Perspektive müsste man jedoch ein seltsames Konstrukt verwenden, um einen Deadlock mit sperrbasierter Parallelität zu erreichen (obwohl ich der Meinung bin, dass es viel einfacher ist, einen Deadlock mit einem Mutex als mit einem Schauspieler zu erstellen). Die Idee ist jedenfalls, dass nur der Transaktionsspeicher garantiert, dass Sie keinen Deadlock haben können, egal für welches seltsame Konstrukt Sie sich entschieden haben.
m3th0dman