MokaByte 99 - 7mbre 2005
 
MokaByte 99 - 7mbre 2005 Prima pagina Cerca Home Page

 

 

 

Soluzioni Oracle per la scalabilità
Oracle Real Application Cluster

Raramente quando si progetta e si implementa una applicazione Java è possibile prevedere il carico di lavoro a regime; il ciclo di vita di una applicazione è variabile ed è possibile che si presentino nuove esigenze (come pre esempio la fusione di due aziende) che richiedano nuova capacità computazionale. Se l'applicazione è mission critical l'aumento di capacità elaborativa dovrebbe avvenire a caldo, senza interruzione del servizio. Oracle offre la funzonalità Real Application Cluster che risponde a tali problematiche.

Introduzione
Una applicazione Java deve, in alcuni contesti, poter garantire la possibilità di poter aumentare la capacità elaborativa senza avere impatti sulla continuità del servizio. Oracle offre, a livello di database, una funzionalità detta Real Application Cluster che permette di poter aggiungere server al database senza dover interrompere il servizio. Real Application Cluster, come si deduce dal nome, è una funzionalità che basa la propria implementazione sul concetto di cluster, ovvero su un insieme di server che condividono una unica area di memorizzazione delle informazioni. La novità interessante è che dalla versione 10 di Oracle la funzionalità RAC è disponibile con la versione standard consentendo di realizzare scalabili a costo contenuto. Lo scopo dell'articolo è illustrare i principi di base del RAC e di comprendere come possa essere utilizzato per lo sviluppo di applicazioni Java.

 

A cosa serve Oracle RAC
Oracle RAC è una soluzione per garantire la scalabiltà più che l'affidabilità; essa presuppone l'utilizzo di un cluster di risorse. Un cluster è realizzato collegando fra di loro server diversi (ma con stesso sistema operativo) detti nodi e condividendo un'area di memorizzazione si disco, in questo modo si riesce ad avere maggiore capacità elaborativa rispetto ad una soluzione che si basa su un server unico. Perchè scegliere un cluster di computer rispetto ad una soluzione basata su un unico server con capacità elabortiva equivalente (ovvero con numero di processori e RAM pari alla somma di qaulli presenti nel cluster)?
Vi sono varie ragioni, a volte non è possibile raggiungere con una singola macchina la capacità elaborativa di più server, inoltre un cluster permette di aggiungere nodi successivamente nel tempo, diluendo l'investimento necessario per far fronte a nuovi carichi di lavoro, in più offre una maggiore affidabilità in quanto, in caso di guasto di un nodo, gli altri continuano a funzionare. Nel caso Oracle sono disponibili delle funzionalità per cui il sistema è in grado di migrare le operazioni di lettura (ovvero le select) da un nodo ad un altro in maniera completamente trasparente e senza nessun intervento da parte dell'utente. La migrazione da un nodo ad un altro viene gestita dal driver per cui si deve solo configurare la stringa di connessione al database in maniera tale da abilitare le funzionalità di failover.
La soluzione RAC non garantisce affidabilità totale in quanto la sua architettura si basa su un elemento condiviso che è l'area di storage, in caso di guasto a quest'ultimo, il sistema si blocca e devono essere avviate le procedure di restore e recovery per poter riutilizzare di nuovo il sistema. L'affidabilità, ovvero la capacità di un sistema di tollerare i guasti (anche i più disastrosi) è garantita dalla funzionalità Data Guard, trattata nel numero scorso (luglio agosto 2005) di Mokabyte.

 

I principi di funzionamento di Oracle RAC
Oracle RAC nella implementazione 10g del database è uno strumento autonomo, ovvero non necessita di software esterno oltre al sistema operativo, questo significa che ha al suo interno tutte le funzioni per gestire il cluster (come, per esempio, l'assegnazione di ip virtuali ai vari nodi) e non è più necessario, come invece accade per la versione 9i, acquistare il software del cluster (HACMP, etc) dal fornitore del sistema operativo. Questo significa che è possibile gestire le operazioni del cluster tramite strumenti Oracle e poter controllare il funzionamento del database e dei nodi attivi con un unico strumento.
La gestione delle funzionalità del cluster e delle relative risorse avviene sia tramite due aree disco dove i vari nodi registrano il loro stato e la loro presenza, sia attraverso un sistema di comunicazione in RAM dove avvengono le sincronizzazioni per l'accesso ai dati e il loro scambio, tale meccanismo di condivisione/scambio delle informazioni in RAM consente di creare una area di memoria virtuale e distribuita fra i nodi che corrisponde a quello che la terminologia Oracle chiama Cache Fusion, ovvero l'unione dei dati presenti nelle SGA (l'area di RAM dove il database fa il caching dei dati e delle istruzioni SQL) delle varie istanze distribuite sui nodi. Oracle RAC è una soluzione trasparente per il programmatore e consente di modificare lo stesso dato su nodi diversi senza che il programmatore debba preoccuparsi se l'informazione da modificare è già in uso da un altro utente; dal punto di vista del programmatore esso appare come un unico server. E' comunque importante sottolineare che, anche se ci viene fornita la trasparenza applicativa, il costo di sincronizzazione per l'accesso ai dati esiste, infatti il sistema deve garantire che in un certo istante un dato sia modificato solo su un singolo nodo, per cui è consigliabile, se possibile di partizionare gli accessi in scrittura, ovvero di modificare i dati sempre sugli stessi nodi. Oltre alla trasparenza Oracle RAC è in grado di fornire due ulteriori funzionalità: il load-balancing ed il failover.
Con load balancing si intende la possibilità di distribuire le connessioni in maniera uniforme fra i vari nodi del cluster in maniera tale che il carico computazionale sia bilanciato nel miglior modo possibile; tale caratteristica è realizzabile in due modi, lato client e lato server. La realizzazione lato client richiede la configurazione della stringa di connessione JDBC in cui si esplicita il parametro LOAD_BALANCE e i nodi su cui si vogliono distribuire le connessioni; è compito del driver jdbc collegarsi ad un nodo piuttosto che ad un altro. La realizzazione lato server richiede la configurazione del listener (il programma che si occupa di accettare le richieste di connessione al database e della loro inizializzazione) in maniera tale che sia in grado di ridirigerle sugli altri nodi in base alle informazioni sul carico computazionale che questi si sono scambiati. In entrambi i casi di configurazione (che possono potenzialmente essere entrambi attivi) il programmatore non deve prendere nessun accorgimento particolare.
La funzionalità di failover consiste, in caso di guasto del nodo sui cui questa stava eseguendo, nella possibilità di ridirigere, sempre in maniera automatica e trasparente, la connessione ad un altro server del cluster. Il failover è disponibile solo lato client e garantisce la perfetta trasparenza solo in caso di lettura, ovvero se si sta eseguendo una select su un nodo e questo esibisce un malfunzionamento il driver è in grado di connettersi ad un altro nodo e di riavviare la select in maniera tale che l'utente finale non si accorga del guasto. Come per il load balancing lato client anche il failover si attiva tramite un parametro nella stringa di connessione JDBC.

 

Funzionalità JDBC Java (thin e OCI)
Oracle fornisce due tipi di dirver jdbc, uno thin (di livello 4, ovvero impelmentato al 100% in java) ed uno thick (di livello 3, in cui il compito del driver è quello di tradurre le istruzioni JDBC in chiamate native al driver Oracle OCI scritto in C), con funzionalità differenti, ovvero il driver thin non offre tutte le possibilità che offre il driver thick. Purtroppo nell'elenco delle caratteristiche mancanti al driver thin c'è la possibilità di fare fail-over, se si sceglie di utilizzare il driver thin sarà possibile sfruttare solo la caratteristica di load balancing. Consideriamo il seguente frammento di codice Java:


DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@" +
"(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = nodo01)(PORT = 1521))" +
"(ADDRESS = (PROTOCOL = TCP)(HOST = nodo02)(PORT = 1521))" +
"(LOAD_BALANCE = yes))" +
"(CONNECT_DATA = (SERVICE_NAME = orcl.noematica.it) " +
"(FAILOVER_MODE =(TYPE = SELECT)(METHOD = BASIC))))",username,password);

La stringa di connessione JDBC consente al driver di collegarsi ad un Oracle RAC che è composto da due nodi (con nome nodo01 e nodo02), ogni nodo ha il listener (il programma che accetta le connessioni al database) in ascolto sulla porta 1521. La connessione è configurata sia per il load balancing, attivata dal parametro LOAD_BALANCE che per il failover tramite la sezione FAILOVER_MODE, ma in realtà è attivo solo il primo. Se subito dopo la connessione (come utente system) si eseguono le istruzioni:

Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select * from v$instance");
rs.next();
System.out.println(rs.getString("instance_name"));

si può notare che successive esecuzioni del programma producono output diversi, in quanto il driver effettua il bilanciamento del carico e si collega a nodi differenti (con istance_name diversi). Se invece si provano le funzionalità di failover, effettuando la stessa query due volte a distanza di 30 secondi, "spegnendo" nel frattempo il nodo a cui ci si era collegati si otterrà un errore che invece non si verifica eseguendo la stessa operazione da un programma "nativo" (come PL/SQL Developer, TOAD, etc) che utilizza la stessa stringa di connessione. Se nella stringa di connessione si cambia il tipo di driver da thin a oci anche i programmi java posso sfruttare il failover trasparente.

 

Conclusioni
Oracle RAC permette, dalla versione 10g del database, di costruire applicazioni scalabili a costo contenuto. Pur non essendo una soluzione che garantisce la completa affidabilità del sistema, esso infatti richiede una area disco comune a tutti i nodi che costituisce un single point of failure, contribuisce ad elevare il livello di dispinibilità del sistema in quanto se un nodo ha un malfunzionamento il sistema continua a funzionare. Oracle RAC fornisce le funzionalità di failover e load balancing che consentono, in maniera trasparente, di blianciare il carico e gestire i guasti a livello di singolo nodo. Purtroppo il diver JDBC thin (quello scritto interamente in java) supporta solo la funzionalità di load balancing e per popter effettuare il failover (per operazioni di lettura) è necessario ricorrere al driver OCI che richiede l'installazione di un client Oracle nativo per la piattaforma su cui si installa l'applicazione Java.

Giovanni Cuccu è laureato in ingegneria informatica a Bologna. Attualmente svolge attività di consulenza per lo sviluppo di applicazioni web tramite Java, Oracle. Si interessa di applicazioni open source, usa Linux regolarmente ed è autore di un Oracle session profiler open source (scritto in Java) scaricabile da http://sourceforge.net/projects/oraresprof/