|
Lo scopo del lavoro è quello di guadagnarsi il tempo libero
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
Terracotta DSO
By
Simone Federici
16 ottobre 2007
|
 |
|
Come tutti sappiamo difficilmente le applicazioni Enterprise girano su una sola JVM. Anche nel caso si tratti di una semplice web application (stateful) all’aumentare degli utilizzatori cresce proporzionalmente la memoria utilizzata (1:1). Inoltre se bisogna garantire che le transazioni utente non devono andare perdute, ad esempio una transazione bancaria, (affidabilità) è necessario replicare le informazioni. Sono cosi entrati a far parte del 90% delle applicazioni due importantissimi requisiti non funzionali: Scalabilità e Affidabilità. - Scalabilità: ossia le capacità di un sistema di “crescere” o “decrescere” in funzione delle necessità e delle disponibilità.
- Affidabilità: ossia la capacità di rispettare le specifiche di funzionamento nel tempo e inoltre la capacità di un sistema di non subire fallimenti anche in presenza di guasti (fault-tolerance).
Java Enterprise ha fornito librerie e nuovi componenti per aiutare le società a produrre software con queste esigenze. In particolare è stata data la possibilità ad una applicazione di girare su un cluster di JVM ossia su un insieme di JVM connesse tra loro allo scopo di distribuire l’elaborazione. Per far comunicare le JVM del cluster, sono stati introdotti protocolli di comunicazione (es. RMI), componenti remoti (es. EJB) e sistemi di messaggistica (es. JMS). Sono nate cosi architetture scalabili verticalmente spostando alcuni componenti in remoto (architettura front-end/back-end) e orizzontalmente bilanciando il carico tramite un load balancer (tipicamente con algoritmo round robin). La tolleranza ai guasti (fault-tolerance) è stata risolta replicando le informazioni (lo stato della applicazione) su più di un server. Ad esempio le sessioni HTTP vengono tipicamente replicate su almeno due nodi del cluster in modo che, se uno di essi dovesse essere spento o subisse un errore, tutte le sessioni utente continuerebbero ad esistere, e non vi sarebbe sospensione del servizio. Uno sviluppatore che deve realizzare un’applicazione con questi requisiti deve quindi agganciarsi a un application server che fornisce tutta questa infrastruttura di componenti e servizi ed imparare ad usarli. OpenTerracotta (da ora in avanti TC) è la prima soluzione di un “cluster trasparente” che senza componenti aggiuntivi o nuove API java da imparare fornisce una infrastruttura in grado di far girare una applicazione java (JSE) su un cluster di JVM, e quindi fornisce già di suo un servizio Scalabile e Affidabile. Possiamo prendere una applicazione sviluppata per girare su una singola JVM (anche se JSE) e “configurarla” in modo che possa essere eseguita su un cluster. Da troppo tempo tendiamo a distinguere i programmatori java dai programmatori JEE come se fossero due mestieri diversi, con Terracotta un buon programmatore, senza utilizzare le infrastrutture/api JEE è in grado di sviluppare una applicazione con requisiti di scalabilità e affidabilità in modo estremamente semplice. L'articolo è stato pubblicato sul blog di Simone Federici
|
|
|
Terracotta Features
|
top
|
Terracotta semplifica lo sviluppo delle applicazioni: - Il cluster TC non è applicativo ma lavora a livello di JVM.
- Permette una netta separazione tra Business Logic e Infrastructure Object.
- NESSUNA API Java NUOVA da imparare.
- Non c’è serializzazione, la replicazione è a livello di field.
- Non ci sono metodi CUSTOM da implementare per la replicazione.
- In poche parole RISOLVE i problemi del CLUSTERING in una sola soluzione
Terracotta features: - Utilizzo della rete ottimizzato, ridotto trasporto delle informazioni (non c’è serializzazione).
- E’ possibile fare l’update degli oggetti (new deploy)
- Monitor del server e degli oggetti condivisi tramite JMX (Admin console)
- Aumento della massima capacita di memoria di una singola JVM.
- Eventi distribuiti.
Tipici scenari: - HTTP Session Replication
- Distributed Cache
- POJO Clustering
- Spring integration
- Collaboration, Coordination, and Events
|
|
Architettura DSO
|
top
|
|
L’architettura è composta da un server centrale (è possibile ridondarlo con una serie di server inattivi) e un insieme scalabile di JVM o Application Server. Ogni JVM comunica con il server tramite delle librerie, caricate in fase di avvio dal boot-classloader, usando un protocollo TCP. 
Generalmente in una JVM i threads interagiscono gli uni con gli altri attraverso il cambiamento degli oggetti residenti nell’HEAP e attraverso le primitive concorrenti native in java (‘synchronized’, wait(), notify() e notifyAll()). Terracotta permette ai threads appartenenti alle diverse JVM del cluster di interagire gli uni con gli altri, modificando gli oggetti di un HEAP “condiviso”, attraverso le stesse primitive di Java, aggiungendo a queste un significato distribuito.
|
|
Librerie DSO
|
top
|
|
Le librerie lette a boot-time dai clients servono a dare, in modo trasparente, un comportamento di cluster a livello di JVM. Prima di tutto aggiungono dei comportamenti distribuiti alle operazioni di salvataggio e cancellazione degli oggetti dell’HEAP, in secondo luogo forniscono uno scambio di informazioni (SIGNALS) centralizzato per avere una sincronizzazione multi JVM. In una JVM, ogni oggetto è salvato in memoria tramite le istruzioni bytecode PUTFIELD e GETFIELD. Terracotta modifica queste istruzioni a runtime, tramite ASM (libreria per la bytecode injection), nelle classi “configurate” che vengono caricate nell’application classloader. Grazie a queste istruzioni, terracotta è in grado di tenere replicati sui server del cluster, interi o parziali grafi di oggetti, comunicando le modifiche degli oggetti e le richieste di lock e unlock al server centrale terracotta. Questo è l’elenco delle istruzioni bytecode modificate: GETFIELD, PUTFIEL, AASTORE, AALOAD, MONITORENTRY, MONITOREXIT, INVOKE0 e INVOKESPECIAL
|
|
TC Server
|
top
|
|
Il Terracotta Server è una applicazione java che usa Berkley DB come database di oggetti. Salva i dati degli oggetti e coordina i threads concorrenti delle diverse JVMs. Tramite un protocollo TCP (p2p) le JVMs comunicano con il TC Server per lo scambio e la sincronizzazione degli oggetti condivisi. TC Server si occupa poi di inviare i dati cambiati a tutti gli altri membri del cluster (se essi ne hanno bisogno).
Terracotta è altamente affidabile in quanto ha la possibilità di ridondare il TC Server, se avviene un crash o un qualsiasi problema di rete nel server attivo, uno degli altri server passivi si attiverà automaticamente in modo da garantire un servizio continuo e fault-tollerant. L’elezione del server attivo avviene tramite un lock master sul FileSystem (berkley) ottenuto mediante un unico processo scrittore, quindi non c’è possibilità di avere un doppio master
|
|
Replicazione
|
top
|
|
Ogni JVM ha un HEAP dove risiedono gli oggetti. Ogni cambiamento ad un oggetto condiviso lo possiamo vedere come una transazione terracotta, questa contiene i cambiamenti degli oggetti, o meglio solo i dati dei campi cambiati. Queste transazioni sono inviate al server e questo immediatamente, invia i cambiamenti a tutte le altre JVM coinvolte lasciando quindi il cluster consistente. Il server filtra ovviamente i dati delle transazioni in modo da mandare i cambiamenti dei soli oggetti posseduti dalle singole JVM. (se una JVM conosce uno solo degli oggetti coinvolti nella transazione, il server gli manderà i soli dati relativi a questo oggetto). Terracotta non usa la Java Serialization per replicare i cambiamenti, gli oggetti sono tracciati e replicati a livello di campo e le transazioni contengono solo dei frammenti di un oggetto anziché tutto il grafo degli oggetti. La Java Serialization ha come principio il salvataggio di un oggetto su uno stream, quindi anche un cambiamento ad un singolo valore, provoca la serializzazione a partire dall’oggetto radice (root) da replicare e quindi la serializzazione di tutto il grafo degli oggetti coinvolti. L’approccio di terracotta è chiaramente molto più efficiente per mantenere sincronizzati due oggetti, infatti essa sposta attraverso il cluster, solo i dati che sono cambiati anziché ogni volta replicare tutto il grafo. La differenza di performance aumentano a dismisura se si pensa ad una struttura condivisa molto profonda. Comunque questo approccio, a parte l’efficienza, risolve un grande problema del clustering: preservare l’identità di un oggetto. Se la serializzazione è usata per spostare un oggetto tra i componenti di un cluster, un oggetto cambiato dovrà quindi essere deserializzato nella JVM remota e “qualcosa” dovrà sostituire l’oggetto esistente con quello passato. Questo è il motivo per cui molte altre tecniche di clustering/caching necessitano di esplicite API (GET/PUT) per la replicazione di un oggetto nel cluster. Terracotta non ha queste restrizioni. Un oggetto condiviso nel cluster, vive nell’HEAP come qualsiasi altro oggetto. Quando un cambiamento ad un oggetto è fatto nella JVM locale, i cambiamenti sono fatti direttamente sull’oggetto dell’HEAP. Quando i cambiamenti sono fatti da una JVM remota, la transazione è ricevuta dalla JVM locale che applica questi cambiamenti sull’oggetto locale (che risiede nell’HEAP). Questo significa che c’è una e solo una istanza di un oggetto condiviso nell’HEAP di ogni JVM. Con TC non bisogna mai richiedere la copia “fresca” dell’oggetto, e nemmeno l’inverso, non è necessario informare nessuno che l’oggetto è stato modificato. Questo perché non ci sono copie, un oggetto condiviso nel cluster è solo un semplice oggetto nell’HEAP e un oggetto condiviso si comporta come ogni altro oggetto: ogni cambiamento effettuato è disponibile immediatamente su tutti gli oggetti che posseggono la reference ad esso, che siano locali alla JVM o remoti. Quindi è importante capire che un oggetto conserva la propria identità in una applicazione eseguita su un cluster TC (multi-JVM) come se fosse eseguita in una singola JVM. La semplicità di Terracotta e la conservazione dell’identità di un oggetto nel cluster, rende i problemi del cluster completamente separati dai problemi di design e implementativi di una applicazione. Le capacità del cluster sono inserite a livello di JVM, fondendosi quindi con l’infrastruttura. Cosi come il garbage collection permette la gestione della memoria in modo trasparente alla programmazione, Terracotta permette la clusterizzazione in modo ugualmente trasparente.
|
|
Virtual Heap
|
top
|
Oltre l’abilità di condividere gli oggetti e i segnali ai threads tra le diverse JVM, Terracotta permette anche un uso efficiente dell’HEAP locale. Infatti un grafo condiviso potrebbe crescere al di sopra delle dimensioni massime raggiungibile da una singola JVM. Terracotta gestisce gli oggetti condivisi in modo da tenere solo gli oggetti di cui la JVM ha bisogno, raggiunta la percentuale di memoria che la JVM può usare per gli oggetti condivisi, solitamente 70% (è configurabile), terracotta libera l’HEAP locale di un 10% tenendosi però delle reference (shadow object) a questi oggetti. Quando la JVM avesse necessità di questi oggetti (missing object), essi verrebbero immediatamente ricaricati dal server. Quindi si può pensare che il cluster Terracotta ha un HEAP virtuale arbitrariamente grande come una enorme memoria di rete. Questa caratteristica permette di avere applicazioni con un HEAP virtuale molto maggiore di un HEAP standard, qualsiasi hardware venga impiegato.
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|