Gestione di dati distribuiti - Implementazione di microservizi in AWS

Gestione di dati distribuiti

Le applicazioni monolitiche, in genere, si basano su un database relazionale di grandi dimensioni, che definisce un singolo modello di dati da applicare a tutti i componenti dell'applicazione. Quando si sceglie di utilizzare i microservizi, un database centralizzato impedirebbe la creazione di componenti indipendenti e decentralizzati. Ogni componente di un microservizio deve disporre del proprio livello di persistenza.

La gestione di dati distribuiti però presenta nuove problematiche. Come conseguenza del teorema CAP, le architetture di microservizi distribuite, per loro natura, sacrificano la consistenza in favore delle prestazioni e sono costrette a fare affidamento sulla consistenza finale.

In un sistema distribuito, le transazioni di business possono comprendere più microservizi. Poiché non possono creare una singola transazione ACID, è possibile che il processo termini con delle esecuzioni parziali. In questo caso, è richiesta una logica di controllo per la ripetizione di transazioni già elaborate. A tale scopo, viene comunemente utilizzato il modello Saga distribuito. Nel caso di una transazione di business non andata a buon fine, il modello Saga orchestra una serie di transazioni compensative che annullano le modifiche apportate dalle transazioni precedenti. AWS Step Functions semplifica l'implementazione di un coordinatore dell'esecuzione del modello Saga, come illustrato nella figura di seguito.

Coordinatore dell'esecuzione del modello Saga

La creazione di un archivio centralizzato per i dati di riferimento critici, governato da strumenti e procedure di gestione dei dati master, offre la possibilità ai microservizi di sincronizzare i dati più importanti ed, eventualmente, di eseguire un rollback. Utilizzando Lambda con una pianificazione di Amazon CloudWatch Events, è possibile realizzare un semplice meccanismo di pulizia e deduplicazione.

Le modifiche di stato molto spesso interessano più di un microservizio. In questi casi, l'event sourcing si è rilevato uno strumento molto prezioso. L'idea di base è rappresentare e consolidare le modifiche di ciascuna applicazione come record di evento. Invece di consolidare uno stato, le informazioni sono memorizzate sotto forma di flussi di eventi. Due esempi molto frequenti di event sourcing sono la registrazione dei log di database e i sistemi di controllo delle versioni. L'event sourcing offre alcuni vantaggi evidenti: gli stati possono essere determinati e ricostruiti in uno storico preciso. Pertanto, produce intrinsecamente un audit trail persistente e semplifica le operazioni di debug.

Nell'ambito delle architetture di microservizi, questo modello permette di disaccoppiare le varie parti di un'applicazione utilizzando pattern pub/sub e inviando gli stessi dati di evento in diversi modelli di dati per diversi microservizi. L'event sourcing viene spesso utilizzato insieme ai pattern CQRS (Command, Query, Responsibility, Segregation) per separare i carichi di lavoro di lettura da quelli di scrittura e ottimizzare prestazioni, scalabilità e sicurezza di entrambi. Nei sistemi di gestione dei dati tradizionali, i comandi e le query sono eseguiti sugli stessi repository di dati.

La figura seguente mostra come implementare il modello di event sourcing degli eventi in AWS. Amazon Kinesis Data Streams funge da elemento principale dello storage di eventi centralizzato che acquisisce le modifiche apportate all'applicazione sotto forma di eventi e li archivia in Amazon S3. La figura illustra tre diversi microservizi composti da Amazon API Gateway, AWS Lambda e Amazon DynamoDB. Le frecce blu indicano il flusso degli eventi: quando il Microservizio 1 rileva una variazione dello stato di un evento, pubblica un evento scrivendo un messaggio in Kinesis Data Streams. Tutti i microservizi eseguono in AWS Lambda una propria applicazione Kinesis Data Streams che legge una copia del messaggio, lo filtra in base alla rilevanza per il microservizio e, se necessario, lo inoltra ad altri servizi per ulteriore elaborazione. Se la funzione restituisce un errore, Lambda effettua nuovi tentativi sui batch finché l'elaborazione non va a buon fine o fino alla scadenza dei dati. Per evitare partizioni bloccate, è possibile configurare la mappatura dell'origine eventi in modo che effettui un nuovo tentativo con una dimensione di batch ridotta, limitare il numero di tentativi o eliminare record troppo vecchi. Per mantenere gli eventi scartati, è possibile configurare la mappatura dell'origine eventi per inviare i dettagli sui batch non correttamente elaborati su una coda Amazon Simple Queue Service (Amazon SQS) o verso un argomento Amazon Simple Notification Service (Amazon SNS).

Modello di sourcing degli eventi attivo su AWS

Amazon S3 memorizza in modo permanente tutti gli eventi di tutti i microservizi e costituisce il SSOT (Single Source Of Truth) per quanto riguarda debug, ripristino dello stato dell'applicazione e verifica delle modifiche. Ci sono due motivi principali per cui i record possono essere distribuiti più di una volta all'applicazione Kinesis Data Streams: nuovi tentativi da parte del produttore e nuovi tentativi da parte del consumatore. Un'applicazione deve prevedere e gestire in modo appropriato l'elaborazione multipla di singoli record.