La società per cui lavoro sta riscrivendo un'applicazione web legacy e stiamo valutando l'architettura migliore per portare a termine il lavoro.
Il dominio aziendale è piuttosto semplice: ci sono poche entità, poche relazioni e semplici regole di business.
Ci aspettiamo un basso numero di scritture simultanee, ma un numero enorme di letture : il carico di lavoro di lettura previsto è molto maggiore del carico di lavoro previsto per la scrittura.
L'applicazione web ha lo scopo di consentire a pochi editor di creare entità chiamate blog che sono composte da post . Ci sono diversi tipi di post: messaggi testuali, foto, link a video di youtube, link a messaggi di Twitter e così via.
Il flusso di lavoro previsto è che un editore, che sta seguendo un evento sportivo dal vivo, è responsabile della modifica di un blog dedicato che è fondamentalmente un flusso di post per l'evento: l'editor crea un post per ogni fatto interessante dell'evento . La preoccupazione principale è avere ogni post disponibile per i client mobile e web il più presto possibile in modo che le persone di tutto il mondo possano seguire l'evento.
Abbiamo valutato due possibili architetture:
- Architettura CQRS con due database diversi uno per lo stack di comandi e uno per lo stack di query
- architettura più semplice con un modello di dominio che supporta sia le scritture che le letture e un database
Il principale vantaggio dell'approccio CQRS è la possibilità di distribuire il contenuto ai client in modo ottimizzato utilizzando alcuni modelli di lettura dedicati per avere letture semplici e veloci dal database del modello letto. In questo modo i lati di lettura e scrittura possono essere ridimensionati in modo indipendente, sfruttando la differenza tra i carichi di lavoro di scrittura e lettura sopra evidenziati.
Il principale vantaggio dell'approccio basato sul modello a dominio singolo è un'architettura molto più semplice. In questo scenario i comandi degli editor vengono elaborati in modo sincrono e quando un comando viene elaborato con successo l'editor sa per certo che il suo lavoro viene salvato all'interno del database e disponibile per i client. Nessuna coerenza finale tra modello di scrittura e modello di lettura, nessuna necessità di gestire il aggiornamento asincrono del modello di lettura dal punto di vista degli utenti dell'interfaccia utente di backoffice (gli editor), nessuna necessità di alcun tipo di sistema di messaggistica coinvolto in attività mission critical.
A mio parere, considerando i nostri requisiti, il modo migliore per procedere consiste nell'utilizzare un'architettura a un singolo dominio e ridimensionare le letture utilizzando una strategia di memorizzazione nella cache aggressiva . L'idea è usare Redis come cache per limitare l'accesso al database e provare ad aggiornare il livello di cache ogni volta che scriviamo qualcosa all'interno del database usando un approccio di streaming (probabilmente useremo Mongo DB e la nostra prima idea è quella di sfruttare la funzione di modifica del flusso ).
Pensi che un database di dimensioni adeguate e una strategia di caching intelligente con redis potrebbe essere sufficiente per gestire le nostre esigenze di lettura? Oppure, al contrario, in uno scenario in cui i carichi di lettura sono molto maggiori dei carichi di scrittura, il modo migliore per procedere è utilizzare un'architettura CQRS (anche a costo di una complessità complessiva più grande)?
Alcune note per chiarire meglio la mia domanda
- Ho menzionato Redis solo come esempio di una cache di memoria distribuita intelligente. L'idea generale sta avendo un meccanismo di caching efficiente per minimizzare l'accesso al database per le letture
- Sono consapevole che un meccanismo di memorizzazione nella cache può essere utilizzato anche quando si adotta un'architettura CQRS (risolvono diversi problemi). Ho evidenziato l'uso di una cache nell'architettura del singolo database perché penso che in tale scenario sia obbligatorio per far fronte al blocco e alla concorrenza sul singolo database utilizzato sia per le scritture che per le letture
- In questa domanda intendo CQRS come un approccio architettonico per un intero contesto limitato (come spiegato qui ) e non come principio di progettazione come originariamente presentato da Bertrand Meyer ( vedi qui )
- Abbiamo pensato a CQRS come a un'architettura possibile perché è una buona scelta quando vuoi scalare in modo indipendente i lati di scrittura e di lettura e vuoi avere dati denormalizzati pronti per essere letti con una singola query (in modo che le letture siano veloci ed efficiente). Allo stesso tempo abbiamo già sperimentato la complessità che CQRS guida e non siamo sicuri che in questo settore valga la pena
- L'obiettivo della mia domanda è ottenere alcuni suggerimenti e feedback (basati su progetti del mondo reale) di persone più esperte in relazione al problema di poter scalare in modo efficiente il lato di lettura delle cose