CQRS: come ripristinare il modello letto

6

È molto interessante come ripristinare il modello di lettura nel sistema basato su CQRS.

In modalità regolare i comandi dei processi di sistema, crea eventi di dominio e li invia al bus dei messaggi. Quindi un'altra parte del sistema (chiamala sottosistema RM) elabora questi messaggi e li salva nel modello di lettura. Questa modalità è abbastanza buona per scopi regolari.

Ma come dovrei riparare il mio modello letto? Ad esempio, l'archiviazione con il modello di lettura è stata danneggiata o ho cambiato la posizione di archiviazione. Voglio che il mio sistema ripristini il modello letto durante l'inizializzazione, prima che le query inizino a provare i dati letti. E voglio sapere la fine del processo di riparazione.

Posso immaginare due modi:

  1. Crea un controller REST, attraverso il quale il mio sottosistema RM sarà in grado di interrogare tutti gli eventi del dominio (nei moduli dei messaggi) e ripristinarlo in modo sincrono.
  2. Crea un meccanismo speciale, chiamando quale mio sottosistema RM sarà in grado di avviare la riproduzione di tutti i messaggi. Per quanto mi riguarda, questa via non è molto buona, perché non posso controllare il tempo di completamento del processo di riparazione. E il secondo, se ci sono altri consumatori di messaggi, probabilmente possono corrompere i loro dati.

Quale via è più preferibile?

    
posta lomomike 03.08.2015 - 11:52
fonte

2 risposte

3

Entrambi i metodi sono assolutamente validi e, come al solito, la risposta è: "dipende".

Il secondo metodo che hai suggerito è facile da implementare e viene usato abbastanza spesso - in particolare, lo considero il metodo standard per portare online nuovi gestori / proiezioni di eventi in un sistema esistente , poiché i nuovi consumatori devono essere ripetuti la cronologia completa degli eventi almeno una volta.

Riguardo agli altri consumatori, per favore non quello

  • puoi (sono tentato di dire dovrebbe ) renderli consumatori identi che, allo stesso tempo, aiutano con il paradigma "almeno una volta" -garantito dei comuni sistemi di bus di messaggi, e
  • puoi sempre scegliere di riprodurre solo eventi in un singolo consumatore, in modo che gli altri utenti non siano interessati dalla riproduzione selettiva.

Inoltre, hai effettivamente misurato il tempo necessario per riprodurre tutti gli eventi in una singola proiezione (quella corrotta)? Solitamente è possibile gestire facilmente decine di migliaia di eventi e leggere gli aggiornamenti dei modelli al secondo (utilizzare un'unica grande transazione), quindi la riproduzione di tutti gli eventi per riparare un singolo modello di lettura dovrebbe essere una questione di minuti. In realtà, riproduciamo tutti gli eventi tutti su ogni all'avvio del sistema, dal momento che il nostro modello di lettura è solo memorizzato ed è estremamente veloce.

Se l'infrastruttura store / messaggistica eventi non supporta la query per tipo di evento, il primo metodo suggerito è un po 'più difficile da implementare, poiché è necessario implementare l'interfaccia di query. Questo potrebbe essere estremamente difficile o potrebbe essere banale, a seconda di come è progettato il tuo negozio di eventi. Quindi se non vuoi utilizzare il secondo metodo che hai suggerito, implementa il 1o metodo, usa le query selettive per riparare un modello di lettura e chiamalo un giorno.

    
risposta data 04.08.2015 - 10:06
fonte
2

Se il modello di query ("modello letto") è memorizzato in un database transazionale completo, normalmente non ci si deve preoccupare di queste cose, perché "riparare un modello di lettura corrotto" dovrebbe essere possibile con il backup / ripristino meccanismo del tuo database. Quindi, supponiamo che questo non sia il caso (forse fai il backup del tuo modello letto solo una volta a notte), mentre il tuo modello di comando è completamente sottoposto a backup (magari in una sorta di registro sequenziale). Ciò significa che una riparazione del modello letto includerà un ripristino dall'ultimo backup e successivamente l'esecuzione dei comandi dal modello di comando. (Nota che il database transazionale funziona internamente con un log delle transazioni che funziona esattamente così, permettendoti di ripristinare il tuo "modello letto" fino al punto immediatamente prima di un arresto anomalo del sistema).

Non sono un esperto di CQRS , ma quando ho capito bene il concetto, c'è un ritardo temporale tra lo stato dei dati nel "modello di query" e lo stato dei dati implicati dal modello di comando. Quindi il tuo sistema dovrebbe essere in grado di gestire comunque la coerenza finale, che è ciò che devi affrontare quando scegli un processo di riparazione asincrono. Pertanto, l'opzione 2 è una soluzione valida, oltre all'opzione 1.

La differenza è che l'opzione 2 potrebbe riportare il sistema più velocemente in linea dopo un danneggiamento del modello di lettura, al prezzo di un intervallo di tempo maggiore finché il modello di query e il modello di comando non sono nuovamente sincronizzati. L'opzione 1 bloccherà il sistema durante il processo di riparazione, ma quando il sistema torna in linea, il ritardo di coerenza tra i due modelli è (si spera) molto più ridotto.

Quindi, ciò che si sceglie dipende dal compromesso accettabile tra disponibilità e coerenza per il particolare sistema e quanto tempo impiegherà il vero "processo di riparazione" per il sistema. Quest'ultimo dipenderà anche dalla velocità del processo di backup / ripristino dei database coinvolti, dalla quantità di dati da elaborare, dal numero di utenti, dal traffico coinvolto e così via.

    
risposta data 03.08.2015 - 13:41
fonte

Leggi altre domande sui tag