Lo sviluppo di una applicazione sul cloud

Si fa molto parlare di cloud, ma se si spera che solo spostando una propria applicazione web da un comune hosting ad un cloud essa diventi scalabile… beh, si è parecchio lontani dalla realtà.
Una applicazione sul cloud non scala automaticamente, deve esserci un sistema in grado di far scalare l’applicazione aprendo nuove istanze all’occorrenza: quindi ci deve essere un approccio sistemistico con un load balancer in grado di dirottare il traffico su più host facendo scalare il sistema. Nella più semplice delle ipotesi, fissiamo un massimo di carico per ciascun application server e usiamo i successivi solo dopo una saturazione del primo; in ipotesi più complesse, sarà lo stesso load balancer in grado di interfacciarsi con le API del proprio IaaS per aprire/chiudere istanze di application server in modo da destinare le risorse della propria infrastruttura a ciò che realmente serve in quel preciso istante.
Sembrerebbe solo una questione sistemistica… invece no: il codice deve essere adatto a lavorare in una simile configurazione e questo lo può fare solo chi sviluppa il codice.
A mio avviso, due sono le cose fondamentali che devono essere tenute in considerazione in fase progettuale: l’architettura del datastore e, ovviamente, gli stati macchina.

Riguardo al datastore, bisogna fare i conti con la qualità/velocità del sistema di memorizzazione del cloud. Chi possiede un proprio cloud, ci tiene che sia totalmente scalabile e, quindi, avrà sia un sistema di virtualizzazione “plug-and-play” ma anche uno storage che ragiona con la stessa logica. Ciascun operatore si affiderà al sistema che più gli aggrada: sul versante opensource, troviamo un discreto numero di filesystem cluster tra cui i più conosciuti sono GlusterFS, Cheph e MooseFS.
Questi filesystem hanno tutti in comune il fatto che per aumentare lo spazio disponibile, è suffuciente aggiungere un nuovo nodo al cluster, quindi il filesystem scala virtualmente all’infinito. Di contro, le prestazioni di un filesystem di questo tipo, in assoluto non sono minimamente paragonabili ad una SAN Fibre Channel, anche se la possibilità di mantenere un considerevole numero di repliche su più server li rende ottimi in situazioni in cui si richiedono molte letture contemporanee ad uno stesso file.
Conoscendo a priori questo limite dell’infrastruttura hardware, si faranno le dovute considerazioni a livello sistemistico riguardo la scelta del datastore più adatto: ad esempio, un comune database relazionale come PostgreSQL o MySQL, nonostante l’abbinamento a sistemi di cache come memcached, non è certo il sistema più adatto, sia perchè richiederebbe una buona velocità del disco, sia per la difficolta nello scalare.
Ultimamente, proprio per far fronte a questo problema, stanno fiorendo molti database del tipo NoSQL che perdono la sintassi e alcune caratteristiche tipiche dell’SQL ma che permettono di avere maggiori prestazioni e un migliore funzionamento in caso di architettura distribuita su più server. Giusto per citarne qualcuno: MongoDB, Cassandra, CouchDB; vi rimando a questo articolo per un confronto tra queste soluzioni.
Ricordiamoci che in una applicazione “sul cloud” il Datastore non è semplicemente il posto dove vengono registrati i dati dell’applicazione ma è il luogo dove vengono registrati TUTTI i dati dell’applicazione. Questo per dire, giusto per fare un esempio, che se la nostra applicazione eseguirà l’upload di una immagine, questa dovrà essere memorizzata sul Datastore e non sul filesystem locale, in modo da evitare problemi di sincronizzazione in caso di utilizzo contemporaneo di più Application Server.

E qui entra in gioco anche l’aspetto degli stati macchina: sebbene abbiamo escluso problemi di sincronizzazione dei dati utilizzando esclusivamente il datastore comune e non il filesystem, ci possono essere alcuni aspetti del nostro applicativo che sfuggono da questa logica: bisogna prestare particolare attenzione agli aspetti legati “a quel particolare server”, tra cui, ad esempio, la gestione delle sessioni e di eventuali sistemi di cache.
Qui ovviamente è solo il programmatore che può farsi carico di questi aspetti, anche se l’utilizzo di framework di sviluppo esplicitamente studiati per realizzare applicativi Cloud-Oriented può facilitargli di molto la vita. Andando “oltre oceano” a vedere come si muovono i colossi vediamo che a fianco di framework già consolidati come Django e Rails, inizia a prendere piede Lift che è un framework basato sul linuguaggio Scala (che deriva da Java); questo framework, sebbene sia più giovane rispetto agli altri citati e quindi non disponga ancora di un ecosistema sviluppato, è stato realizzato avendo in mente proprio la scalabilità su più application server. Facendo un paragone con Ruby, Scala è molto più performante anche se è molto più esoso nell’utilizzo della RAM.

Foursquare, il social network geografico, è un big che utilizza esclusivamente Lift con database MongoDB.
Giusto per citare un altro caso, Twitter è una web application realizzata per lo più in Ruby on Rails, però recentemente ha riscritto la parte più interna del codice della timeline in Scala usando come datastore Redis, proprio per migliorarne la scalabiltà.

In Italia, Python/Django e Ruby on Rails stanno prendendo piede in questi anni e, purtroppo, non esiste ancora una offerta di soluzioni hosting dedicate a questi sistemi comparabile con i comuni stack LAMP. In qualsiasi caso, il futuro locale secondo me sarà su questi due framework. però, per un programmatore appena uscito dall’Università dove ha sbattuto la testa per anni su Java e che ha mire di lavoro anche oltre oceano, reputo che sia importante (e meno impegnativo) approfondire Scala/Lift prima di dedicarsi allo studio di Python/Django e Ruby on Rails che sarebbero per lui totalemte nuovi.