2015-10-22 46 views
15

Event sourcing e CQRS sono ottimi perché gli sviluppatori si bloccano con un database pre-modellato con cui lo sviluppatore deve lavorare per tutta la vita dell'applicazione, a meno che non ci sia un progetto di migrazione di grandi quantità di dati. CQRS e ES hanno anche altri vantaggi come scalare eventstore, log di controllo ecc. Che sono già presenti su Internet.Quali sono gli svantaggi dell'utilizzo di Event sourcing e CQRS?

Ma quali sono gli svantaggi?

Qui ci sono alcuni svantaggi che mi viene in mente dopo la ricerca e la scrittura piccola demo apps

  1. Complex: Alcune persone dicono ES è complessa. Ma direi che avere un'applicazione complessa è meglio di un modello di database complesso su cui è possibile eseguire query molto ristrette utilizzando un linguaggio di query (più join, indici ecc.). Voglio dire che alcuni linguaggi di programmazione come Scala hanno una libreria di raccolta molto ricca che è molto flessibile per produrre alcune aggregazioni seriamente complesse e inoltre c'è Apache Spark che rende facile la raccolta di query distribuite. Ma i database saranno sempre limitati alle sue capacità di linguaggio di query e la distribuzione dei database è più difficile del codice applicativo distribuito (Basta distribuire un'altra istanza su un'altra macchina!).
  2. Utilizzo spazio su disco elevato: l'archivio eventi potrebbe finire con l'utilizzo di molto spazio su disco per memorizzare eventi. Ma possiamo pianificare una pulizia ogni poche settimane e creare uno snapshot e potrebbe essere possibile archiviare eventi storici localmente su un HD esterno, nel caso in cui avessimo bisogno di vecchi eventi in futuro?
  3. Utilizzo memoria alta: lo stato di ogni oggetto dominio è archiviato in memoria, il che potrebbe aumentare l'utilizzo della RAM e la memoria RAM è costosa. GRANDE PROBLEMA !! perché sono povero! qualche soluzione a questo? Si può usare Sqlite invece di memorizzare lo stato in memoria? Sto rendendo le cose più complesse introducendo più istanze di Sqlite nella mia applicazione?
  4. Tempo di avvio più lungo: in caso di errore o di aggiornamento del software l'avvio è lento a seconda del numero di eventi. Ma possiamo usare le istantanee per risolvere questo?
  5. Consistenza finale: Problema per alcune applicazioni. Immagina se Facebook utilizzasse Event source con CQRS per archiviare i post e considerando quanto sia affollato il sistema di Facebook e se ho postato un post vedrei il mio post fb il giorno successivo :)
  6. Eventi serializzati nel negozio Eventi: Eventi store eventi del negozio come oggetti serializzati, il che significa che non possiamo interrogare il contenuto degli eventi nell'archivio eventi che è comunque scoraggiato. E non saremo in grado di aggiungere un altro attributo all'evento in futuro. La soluzione sarebbe di memorizzare eventi come oggetti JSON invece di eventi serializzati? Ma è una buona idea? Oppure aggiungi altri eventi per supportare la modifica dell'oggetto evento originale?

Qualcuno può commentare gli svantaggi che ho portato qui e correggermi se ho torto e suggerire un altro che potrebbe essermi perso?

+2

Perché lo stato di ogni oggetto dominio è memorizzato? gli oggetti del dominio vengono ricreati dagli eventi quando sono necessari. Perché dovresti pensare che FB non userebbe l'event sourcing, solo perché sono occupati?La mia comprensione è che usano un singolo master di scrittura e diversi read slave che sincronizzano "alla fine", quindi usano la coerenza finale, che è il motivo per cui a volte puoi pubblicare qualcosa e poi non vederlo nel tuo feed. –

+0

Ha senso! Ma la ragione per cui ho pensato che lo stato dell'oggetto dominio sarà memorizzato in memoria perché sono costosi da ricreare. Spingi davvero migliaia di eventi per oggetto dominio ogni volta che c'è un aggiornamento per 1 attributo di tale oggetto dominio? e immagino di aver sbagliato su FB non usando l'event sourcing. Grazie :) – hajime

+1

di solito non avresti migliaia di eventi per oggetto, ma se lo facessi potresti non essere lento come pensi (selezione semplice senza join per ottenere gli eventi) e poi applicato in memoria. È sempre possibile "snapshot" degli eventi per un oggetto se questo è effettivamente dimostrato essere un problema durante il perf testing. –

risposta

23

Ecco la mia opinione su questo.

  1. CQRS + ES può rendere le cose molto più semplici in sistemi software complessi per avere oggetti ricchi di dominio, modelli di dati semplici, il monitoraggio storia, maggiore visibilità in problemi di concorrenza, la scalabilità e molto altro ancora.Richiede un modo diverso di pensare ai sistemi, quindi potrebbe essere difficile trovare sviluppatori qualificati. Ma CQRS semplifica la separazione delle responsabilità tra gli sviluppatori. Ad esempio, uno sviluppatore junior può lavorare esclusivamente con il lato di lettura senza dover toccare la logica di business.

  2. Le copie di dati richiedono sicuramente più spazio sul disco. Ma lo stoccaggio è relativamente economico in questi giorni. Potrebbe richiedere che il team di supporto IT esegua più backup e pianifichi come ripristinare il sistema nel caso in cui le cose vadano storte. Tuttavia, la virtualizzazione dei server in questi giorni rende il flusso di lavoro più snello. Inoltre, è molto più semplice creare ridondanza nel sistema senza un database monolitico.

  3. Non considero l'utilizzo della memoria più elevato un problema. L'idratazione degli oggetti aziendali dovrebbe essere effettuata su richiesta. Gli oggetti non dovrebbero mantenere riferimenti ad eventi che sono già stati mantenuti. E l'idratazione dell'evento dovrebbe avvenire solo quando i dati persistono. Dal lato della lettura non hai le conversioni Entity -> DTO -> ViewModel che di solito accadevano nei sistemi a livelli e non avresti alcun tipo di tracciamento delle modifiche agli oggetti che gli ORM con funzionalità complete di solito fanno. La maggior parte dei sistemi esegue letture significativamente maggiori rispetto alle scritture.

  4. Il tempo di avvio più lungo può rappresentare un piccolo problema se si utilizzano più database eterogenei a causa dell'inizializzazione di vari contesti di dati. Tuttavia, se si utilizza qualcosa di semplice come ADO .NET per interagire con l'archivio eventi e un micro-ORM per il lato di lettura, il sistema si "avvia a freddo" più rapidamente di qualsiasi ORM completo. L'importante è non complicare eccessivamente il modo in cui accedi ai dati. Questo è in realtà un problema che CQRS dovrebbe risolvere. E come ho detto prima, il lato di lettura dovrebbe essere modellato per le viste e non avere alcun sovraccarico di re-mapping dei dati.

  5. Il commit a due fasi può funzionare bene per i sistemi che non hanno bisogno di scalare per migliaia di utenti nella mia esperienza. Dovresti scegliere i database che funzionerebbero bene con il coordinatore delle transazioni distribuite. PostgreSQL può funzionare bene per leggere e scrivere modelli separati, per esempio. Se il sistema ha bisogno di scalare per un numero elevato di utenti concorrenti, dovrebbe essere progettato tenendo presente la coerenza finale. Ci sono casi in cui si dovrebbero avere radici aggregate o limiti di contesto che non usano CQRS per evitare la coerenza finale. Ha senso per le parti non collaborative del dominio.

  6. È possibile eseguire query di eventi in formato serializzato come JSON o XML, se si sceglie il database corretto per l'archivio eventi. E questo dovrebbe essere fatto solo per scopi di analisi. Niente all'interno del sistema deve interrogare l'archivio eventi con qualcosa di diverso dall'ID radice aggregato e dal tipo di evento. Tali dati dovrebbero essere indicizzati e vivere al di fuori dell'evento serializzato.

+0

Grazie per una risposta molto dettagliata. Questo ha reso le cose molto più chiare per me. – hajime

+0

Voglio solo aggiungere al punto 5. Dovremmo evitare due commit di fase. La soluzione migliore è sempre iscriversi all'archivio eventi e gestirlo quando possibile, ma non legare l'archivio eventi a una transazione distribuita – Narvalex

3

Giusto per commentare punto 5. mi è stato detto che Facebook fa uso di ES con coerenza eventuale, che è il motivo per cui a volte è possibile vedere un post scomparire e riapparire dopo che hai postato.

In genere il modello di lettura a cui accede il browser si trova "vicino", ma dopo aver effettuato un post, SPA passa a un modello di lettura che si trova vicino al modello di scrittura. La stretta vicinanza tra il modello di scrittura (eventi) e il modello di lettura significa che puoi vedere il tuo post.

Tuttavia, 15 minuti dopo la SPA torna al primo modello di lettura più vicino. Se l'evento che contiene il tuo post non si è ancora propagato a quel modello di lettura, vedrai il tuo post sparire solo per riapparire qualche tempo dopo.