…non è chimica…è piuttosto:

image

 

“Eventually consistent”!! Splendido. Quando ho visto questa slide ho avuto una di quelle strane sensazioni di gioia che solo uno della ns categoria può avere…un po’ come quando vedi Hejlsberg creare un interprete c# in 3 minuti usando c# 4.0 (ma quella è un’altra storia).

Sono un informatico però, non un filosofo. Un sistema o è consistent o non lo è…

Eppure non posso negare che il il brivido alla schiena ci sia stato. E questo mi ha fatto ripensare (Lorenzo ci fece pensare già qualche anno fa).

Ho pensato ai diversi sistemi distribuiti che ho sviluppato seguendo i più rigidi principi ACID, quindi facendo uso di 1 o più databases e transazioni distribuite (si noti il fatto che si parla di transazioni distribuite, non locali). Una cosa che tutti hanno in comune è che quei principi ACID rendono il sistema una bella black box assolutamente indivisibile. Un problema di prestazioni di un componente diventa un problema di tutto il sistema. I database, dove la consistenza deve essere garantita, diventano il bottleneck. E’ difficilissimo scalare linearmente un tale sistema e men che meno scalarne solo alcune porzioni alla volta. 

Troppe volte ho visto use cases mostruosi dove il sistema doveva fare di tutto e ovviamente in maniera sincrona e consistente. Troppe poche volte ho visto (mea culpa) gli sviluppatori (architetti, analisti, chiamateli come volete) opporsi e cercare di spiegarne le implicazioni. Troppo spesso tendiamo a concentrarci sui particolari e a dimenticare il grande schema. Per esempio, oggi, DTC e WCF rendono tutta la gestione di transazioni distribuite un giochetto; i dettagli sono facili, quindi troppo spesso diciamo: “non c’è problema, sappiamo farlo”. Ma il problema non è se sappiamo farlo o no, ma piuttosto se è giusto farlo. Se è sostenibile in termini di scalability e availability. Se non esistono alternative.

Intendiamoci, ogni sistema ha i suoi requisiti, quindi in diversi casi questa riflessione non si applica e l’approccio classico può andare benissimo; è provato che funziona e dà garanzie e comodità notevoli (vedi DTC). Ma tale comodità e garanzie hanno un costo…e sarebbe nostro dovere conoscerlo. 

Tutto va bene e tutto ci viene perdonato finché abbiamo un numero di utenti limitato. Ma siamo sicuri che l’applicazione regga anche nel caso (magari!) che diventi così popolare che il carico di visite giornaliere cresca di ordini di grandezza? Siamo sicuri che scali linearmente (o quasi) e senza richiederci salti mortali? Siamo sicuri che l’availability non degradi?

Una transazione distribuita si basa sul protocollo “2 phase commit” che, quando implementato insieme a tecniche di recovery e fault tolerance garantisce che la mia operazione sia Atomica, Consistente, Isolata e Durabile. Ma per farlo deve imporre che le risorse coinvolte aspettino. In altre parole è un protocollo bloccante. Il suo più grosso limite è quindi che rende tutte le parti coinvolte accoppiate e dipendenti l’una dall’altra. Non si scappa…posso progettare la mia architettura come una SOA, super disaccoppiata in termini di interfacce e oggetti scambiati, ma se le comunicazioni tra i diversi attori avvengono in maniera sincrona e sotto transazione distribuita, ho riaccoppiato il tutto...e allora forse era meglio un’architettura monolitica (uhh ho detto l’eresia!). Mi correggo…magari era meglio progettare le comunicazioni tra i diversi attori diversamente, valutare meglio i boundaries e pensare a compromessi sulla consistency. In fondo, le procedure manuali che i nostri sistemi tentano di automatizzare non sono mai 100% coupled e sincrone. Ma qui mi fermo perché non farei altro che ripetere considerazioni di altri molto più saggi di me.

Concludo questa mia riflessione notando che le architetture di EBay e di Amazon sono in un qualche modo simili nella scelta di un approccio che non segue i principi ACID nella maniera più ortodossa e anche Microsoft (un po’ in ritardo) sta aggiustando il tiro nella sua proposta con Dublin e Azure (forte attenzione alla scalabilità attraverso queues, operazioni asincrone, db denormalizzati, etc.).

Prepariamoci ad un futuro che sarà si consistent, ma non subito…eventually! :)

 

P.S.: anche se non c’entra nulla, ma visto che l’ho menzionato, riporto il link al video di Anders Hejlsberg – guardatevi (se non l’avete già fatto) almeno gli ultimi 15 minuti e ditemi se quell’interprete c# creato dinamicamente al volo non vi provoca un momento di geek excitment :-)