Perché Akka è buono per la concorrenza?


9

Sono nuovo di Akka e attore - sono sicuro che mi manca qualcosa di ovvio, per favore accetta le mie scuse in anticipo.

Continuo a leggere che uno dei punti principali per scegliere Akka è il modo in cui gestisce la concorrenza.

Non mi è chiaro perché Akka sia così speciale; Capisco che ci sono molti piccoli attori che sono molto leggeri e veloci; tuttavia, come può aiutarmi quando due utenti salvano un modulo contemporaneamente?

Non avrei ancora bisogno di una sorta di blocco della concorrenza (pessimista / ottimista / ecc.)?


Stai chiedendo perché gli attori fanno bene alla concorrenza o in particolare a Akka?
scriptin

Wouldn't I still need some sort of concurrency lock (pessimistic/optimistic/etc..)?- Sì, ma questa è la responsabilità del RDBMS sottostante, non dell'attore. Molto probabilmente l'attore Akka non sta parlando direttamente con il tuo utente. Piuttosto, l'attore Akka e l'utente (essenzialmente un altro attore) interagiscono direttamente con il database.
Robert Harvey,

Risposte:


7

Uno dei vantaggi dei modelli di elaborazione dei messaggi come attori e agenti è che i tradizionali problemi di concorrenza (principalmente la sincronizzazione dello stato condiviso) non rappresentano più un problema. L'attore può mantenere lo stato privato e aggiornarlo liberamente senza blocchi. Il framework degli attori assicura che venga elaborato un solo messaggio alla volta. Con l'elaborazione serializzata, il codice può essere scritto in un modo senza blocco.

Nel tuo esempio di utenti che salvano un modulo, supponendo che l'attore conservasse un Elenco di alcuni dati da ciascun modulo, l'attore può aggiornare l'elenco senza blocchi, poiché il framework garantisce che verrà elaborato un solo modulo alla volta. Tradizionalmente, dovresti bloccare gli accessi all'elenco o utilizzare un elenco simultaneo.

La strategia di concorrenza è una questione leggermente diversa ed è ancora una tua responsabilità (nessuna strategia è la strategia più comune). Per cambiare leggermente il tuo esempio, supponiamo che entrambi gli utenti provino ad aggiornare contemporaneamente l'istanza del modulo SAME. Senza strategia di concorrenza, i cambiamenti di uno sovrascriveranno l'altro (probabilmente l'ultimo vince). Va bene, ma nella migliore delle ipotesi ciò comporta un comportamento imprevisto per l'utente le cui modifiche sono state sovrascritte. Se visualizzano il modulo che hanno appena modificato, avrà valori imprevisti (dall'altro utente). Nel peggiore dei casi (quando non stiamo parlando solo di aggiornamenti dei moduli, ma di cose come gli ordini di spedizione), potrebbero verificarsi perdite di vario tipo (tempo, entrate, ecc.).

L'uso di una strategia di concorrenza consente di identificare questi casi e di risolverli in base alle regole aziendali. Ad esempio, la concorrenza ottimistica consente all'utente di inviare la versione del modulo che sta aggiornando. Quando l'attore esegue l'elaborazione della modifica, nota che il secondo utente pensa che stia aggiornando la versione 5 quando il modulo è effettivamente alla versione 6 a causa dell'aggiornamento del primo utente. Ora almeno possiamo avvisare il secondo utente che il modulo è già cambiato da quando hanno iniziato a modificarlo. O qualunque siano le regole che l'azienda vuole far rispettare lì.

Nel caso dell'aggiornamento di un modulo, probabilmente non ti interessa molto della concorrenza (dipende, immagino). Ma in altri casi, può essere una cosa molto importante almeno essere in grado di controllare e gestire le violazioni. Potresti anche voler ignorare la violazione della concorrenza, come se gli utenti cambiassero diverse sezioni (per continuare l'analogia del modulo). O se la modifica ha un grande impatto sull'azienda (un grosso ordine), si desidera accettarla e risolvere conflitti minori in seguito (ad es. L'aggiornamento annuale delle informazioni di contatto non è stato completato).

Credo che Akka abbia una serie di altre dimensioni come il modo in cui gestisce i guasti, i supervisori, ecc. Che sono considerazioni importanti per gli sviluppatori.


9

Scriverò sul modello di attore in generale (non solo su Akka) rispetto ad altri modelli di concorrenza come la classica concorrenza basata su lock e la memoria transazionale ordinata.

vantaggi

  1. Concetto più semplice da capire e da usare

    • La concorrenza basata sul blocco è difficile; in particolare è molto difficile farlo bene perché ci sono molti concetti da capire e usare per essere corretti ed efficienti: blocchi, semafori, thread, sincronizzazione, mutua esclusione, barriera di memoria ecc.

    • Gli attori, d'altra parte, sono un concetto più astratto; hai attori che inviano e ricevono messaggi. Non è necessario afferrare e utilizzare concetti di basso livello come la barriera della memoria.

  2. Fa rispettare l'immutabilità

    • La mutabilità è una fonte di molti errori e bug nella programmazione, specialmente nelle applicazioni multi-thread. Il modello dell'attore risolve questo problema applicando l'immutabilità.
  3. Meno soggetto a errori

    • Per i due motivi sopra indicati
  4. Efficiente

    • Non efficiente quanto una buona scrittura basata su lock ma in generale più efficiente della memoria transazionale del software.
  5. Facilmente scalabile

    • Teoricamente almeno, l'applicazione dovrebbe ridimensionarsi abbastanza bene aggiungendo più attori per svolgere il tuo lavoro. Con il lock-based è piuttosto difficile scalare.

svantaggi

  1. Non tutte le lingue impongono facilmente l'immutabilità;

    • Erlang, il linguaggio che per primo ha reso popolari gli attori ha l'immutabilità al suo centro ma Java e Scala (in realtà la JVM) non impongono l'immutabilità.
  2. Ancora piuttosto complesso

    • Gli attori si basano su un modello asincrono di programmazione che non è così semplice e facile da modellare in tutti gli scenari; è particolarmente difficile gestire errori e scenari di fallimento.
  3. Non impedisce deadlock o fame

    • Due attori possono essere nello stato in attesa di messaggi l'uno dall'altro; quindi hai un deadlock proprio come con i lock, anche se molto più facile da eseguire il debug. Con la memoria transazionale, tuttavia, si è garantiti senza deadlock.
  4. Non così efficiente

    • A causa dell'immutabilità forzata e perché molti attori devono passare a utilizzare lo stesso thread gli attori non saranno efficienti quanto la concorrenza basata su blocchi.

Conclusione

La concorrenza basata su lock è la più efficiente ma è difficile da programmare e soggetta a errori; la memoria transazionale del software è la più chiara, facile da programmare e soggetta a errori, ma è anche la meno efficiente. Gli attori si trovano a metà strada tra questi due modelli con tutti gli aspetti: facilità di programmazione, efficienza e propensione all'errore.


Per il tuo vantaggio numero 2, non dovrebbe essere "La mutabilità è una fonte di molti errori ..." e "... risolve questo problema vietando la mutabilità " anziché "l' immutabilità "? Inoltre, la seconda frase ha due menzioni ridondanti per risolvere il problema.
settembre

@ 8bittree Sì, hai ragione; ho scritto male. Nel caso non lo sapessi, puoi modificare le risposte per correggere tali problemi.
m3th0dman,

Ne sono consapevole, sono solo riluttante a fare cambiamenti che invertono o cambiano drasticamente il significato di qualcosa nel caso in cui sia un malinteso da parte mia.
8bittree,

Puoi approfondire il deadlock? Sembra che dovresti costruire una configurazione dell'attore molto imbarazzante (comunicazione bidirezionale) per imbatterti in quello. Se stai usando un modello in stile ask (A chiede a B una risposta, B elabora la richiesta e risponde al mittente della richiesta ma non contatta mai direttamente A) Non vedo come sia possibile un deadlock
Daenyth,

1
@Daenyth Sono d'accordo che dovresti usare uno strano costrutto per raggiungere un punto morto con gli attori; ma da una prospettiva simile dovresti usare uno strano costrutto per raggiungere un deadlock con concorrenza basata su lock (anche se sono d'accordo che è molto più facile creare un deadlock con un mutex che con un attore). Ad ogni modo, l'idea è che solo la memoria transazionale garantisce che non si può avere un deadlock, indipendentemente dallo strano costrutto che si è scelto di implementare.
m3th0dman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.