2014-09-22 2 views
14

Non sono abbastanza sicuro di come gli attori possano essere utilizzati per accedere al database. Nella documentazione e nei libri per Akka questo argomento sembra essere omesso.Come utilizzare gli attori per l'accesso al database e DDD?

Una soluzione può essere un DAO avvolto in un attore senza stato. Ad esempio, per ogni tabella (o tipo di oggetto di dominio o tipo di aggregazione) nel database è possibile creare un attore responsabile di tutte le operazioni CRUD. Una variazione di questo può essere una separazione di comandi e query. Ad esempio per ciascun tipo di dati 1 comando attore (per concorrenza) e 10 query attori (per parallelismo).

Un altro approccio potrebbe essere quello di creare attori stateful che rappresentino esattamente una riga (o un'istanza dell'oggetto dominio o un'istanza aggregata) nel database. Naturalmente il database può essere in questo caso anche un archivio di eventi (come il modulo di persistenza akka) con una proiezione alla fine coerente a un database, un archivio di documenti o una cache. Questo non è rilevante qui. Questo approccio è in realtà un'implementazione di una cache in memoria con tutti i vantaggi e i problemi. Ci deve essere una strategia per distruggere gli attori per non rimanere a corto di memoria dopo un po '.


io dirigerò la mia domanda per DDD:

Diciamo, voglio sviluppare un'applicazione DDD con attori Akka. Concentriamoci qui sulla parte di comando. A mio avviso, questo dovrebbe essere implementato in questo modo: per ogni contesto limitato ci sarà un attore portuale, ad es. Spray REST API, che indirizza i messaggi all'appropriato attore del servizio di dominio. Questo attore del servizio coordina un'attività commerciale a uno o più aggregati di modelli di dominio. Ogni singolo aggregato è un attore di stato che viene ripristinato (o creato su nuovi dati) dall'attore del servizio dal database. L'attore del servizio invia/indirizza i messaggi a tutti gli attori aggregati coinvolti. Gli attori del modello di dominio ricevente eseguiranno la convalida aziendale sul loro stato + messaggio e quindi scriveranno le loro modifiche al database, ad es. DAO chiari. Dopo aver inviato un nuovo done all'attore del servizio, vengono arrestati. Al termine di tutti gli attori aggregati, un messaggio done viene rinviato al mittente del messaggio. Una variazione potrebbe essere quella di non fermare immediatamente gli attori del modello a dominio statistico, ma dopo un periodo di tempo, diciamo 3 minuti.

È un modello di utilizzo valido per DDD con Akka?

+0

Non capisco perché questo ottiene voti ravvicinati. Ho anche sempre trovato che l'accesso ai dati è un argomento nebuloso/non ben documentato nelle piattaforme Modello attore. Penso (ma non ho provato) che un approccio di Event Sourcing si fonderebbe bene con la roba degli attori dato che i messaggi degli attori sono immutabili. Un aggregato invierebbe un messaggio al mondo (cioè un attore del dispacciamento) contenente il suo nuovo stato. Quindi un attore di persistenza sarebbe responsabile di aggiungere questo nuovo stato all'archivio degli eventi. Altri attori potrebbero agire basandosi su quel messaggio su una base ad hoc. – guillaume31

+1

Event Sourcing è già una funzionalità incorporata in Akka. Non l'ho ancora provato perché sono nuovo di Akka ed è un richiamo alla complessità per me. Vedi http://doc.akka.io/docs/akka/snapshot/scala/persistence.html – Sebastian

+2

Per il mio futuro: Ricordati di leggere il libro * Reactive Enterprise with Actor Model: Modelli di applicazione e integrazione per Scala e Akka * di ** Vaughn Vernon ** primavera 2015 [Amazon] (http://www.amazon.co .uk/dp/0133846830 /) – Sebastian

risposta

4

In genere le operazioni di lettura DB (cRud) possono essere eseguite direttamente da qualsiasi attore. Non è necessario effettuare alcuna manipolazione speciale nella maggior parte dei casi. Solo un semplice round robin per bilanciare il carico.

Come per le operazioni di aggiornamento (CrUD), possono essere suddivisi in domini/frammenti non intersecanti. Ad esempio, tutte le operazioni con un singolo account dovrebbero essere preferibilmente elaborate da un singolo attore. Uno può avere N attori di elaborazione quasi indipendenti e un router che indirizza i comandi a uno di essi sulla base dell'account.hashCode% N, ad esempio. Pertanto le operazioni verranno distribuite tra gli attori più o meno uniformemente e ogni account verrà elaborato in sequenza.

P.S. Slick sembra essere una libreria di db di discesa per le applicazioni Akka.

+1

Hai detto di creare un comando-attore per dominio o frammento? Ma cosa fa questo attore? Questo attore è responsabile di tutte le entità e esegue operazioni di aggiornamento del database da solo? O sarebbe un attore di primo piano per altri attori per il principio di responsabilità unica? Se il secondo, la mia domanda rimane sempre la stessa: gli altri attori (più profondi nella gerarchia) sarebbero attori statali di DAO (Transaction Script) o attori di stato "Active Record" per esempio. uno per ogni entità distinta o aggregato? – Sebastian

+0

(1) Un attore per frammento serializza le operazioni con un sottoinsieme di entità riducendo così la possibilità di riordinare i messaggi. (I sottoinsiemi gestiti da diversi attori non si incrociano meglio.) (2) L'attore è responsabile della gestione di entità di qualsiasi tipo, (tuttavia è possibile distribuire entità tra diversi attori se la chiave di sharding contiene un tipo di entità). (3) Per l'accesso ai dati effettivi, DAO è preferibile e può essere eseguito in sicurezza dallo stesso attore o delegato ai bambini. –

+0

Sì, grazie! Implementerò CrUD in questo modo (per shard o attore di dominio), ma con attori bambini apolidi per elaborare transazioni non incrociate in parallelo e dividere la logica di business in parti più piccole (ovvero aggregati con un invariante). – Sebastian