L'approvvigionamento di eventi è disponibile solo quando le scritture sono rare?


9

Sto leggendo sull'approvvigionamento di eventi e non riesco a smettere di chiedermi se ha senso solo in situazioni esotiche in cui le scritture sono molto rare o è richiesto un controllo di livello militare.

Un sistema non eccezionale con un uso significativo potrebbe produrre tra centinaia e migliaia di scritture al giorno, traducendo, per esempio, in un milione o 2 scritture (quindi eventi) per anno di funzionamento. Unire milioni di oggetti (eventi) solo per ottenere lo stato attuale suona come una proposta ridicola, se confrontato con una lettura semplice da un archivio tradizionale. Tuttavia, il sourcing degli eventi è alla base di alcuni dei sistemi più performanti (pensate a LMAX).

Quindi, cosa mi sto perdendo? Il ripristino dello stato dal flusso di eventi è anche comunemente eseguito? Oppure l'idea è quella di doverlo fare raramente e di utilizzare invece una memoria completamente diversa per le normali operazioni (ovvero utilizzare la memoria Query da CQRS) e ripristinare dagli eventi solo in casi eccezionali (come la replica, il controllo, ecc.)?

Risposte:


6

Quindi, cosa mi sto perdendo?

Indovinare.

La prima cosa che potresti perdere è che devi solo ricaricare gli eventi per lo stato che stai ricostruendo. Se è possibile modellare in modo pulito i limiti delle transazioni, ogni oggetto può scrivere gli eventi contrassegnati con il proprio ID e quindi rileggere solo quegli eventi. Usando un database relazionale per l'archiviazione di eventi, ci sarebbe una colonna id indicizzata per velocizzare quella query. Usando EventStore, ogni oggetto avrebbe il suo flusso.

Ci vuole un po 'di cura nel tuo modello per farlo in modo pulito, poiché vuoi essere sicuro che stai modificando solo un singolo oggetto in ciascuna transazione, e quindi devi fare attenzione a isolare correttamente ogni invariante che stai cercando di imporre.

Nei casi in cui ciò non è abbastanza veloce, hai ancora la possibilità di creare istantanee del tuo stato (memoization) e persistere in "archiviazione tradizionale". Ogni istantanea viene taggata con il numero progressivo dell'ultimo evento utilizzato per creare l'istantanea; al ricaricamento, il repository acquisisce prima l'istantanea, quindi applica eventi più recenti. (Ciò implica un modo ragionevole per catturare le istantanee più recenti: o gli eventi sono anche taggati con il numero di sequenza, oppure hai un modo efficace per leggere il flusso di eventi all'indietro fino ad arrivare al punto di partenza.)

C'è ancora un vantaggio rispetto al solito approccio qui, dato che le tue istantanee possono essere costruite parallelamente alle tue scritture, piuttosto che essere fuse con loro: hai semplicemente messo un listener di eventi in qualche altro thread / processo e lo hai lasciato allegramente lungo la scrittura al negozio di istantanee su qualsiasi programma sembra ragionevole. Dopotutto, l'istantanea non deve essere particolarmente tempestiva - abbastanza spesso che il lavoro di riapplicare gli eventi più recenti non fa esplodere il tuo SLA.

(Le snapshot complicano la migrazione; eventuali modifiche alla serializzazione del modello invalideranno la cache delle snapshot. Naturalmente, è possibile ricostruire snapshot utilizzando la nuova serializzazione come parte della migrazione e quindi "recuperare" quando le modifiche diventano attive.)

Il ripristino dello stato dal flusso di eventi è anche comunemente eseguito?

Sì. Ciò che normalmente viene mostrato negli esempi CQRS è che il livello Applicazione, dopo aver verificato che il comando inviato sia ben formato, il livello applicazione caricherà l'oggetto di dominio da un repository, dove il carico è un costruttore predefinito seguito da una riproduzione del flusso di eventi (o equivalentemente, una chiamata a una fabbrica con un elenco di eventi).

Altri due pensieri contraddittori.

  1. Potrebbe esserci una cache dietro l'interfaccia del repository
  2. L'invalidazione della cache è uno dei due problemi principali.
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.