Soluzioni Oracle per la scalabilità

Come rendere scalabili le applicazioni Oracledi

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 che richiedono nuova capacità computazionale. Se l‘applicazione è mission critical, l‘aumento di capacità elaborativa dovrebbe avvenire a caldo, senza interruzione del servizio. Oracle offre la funzionalità 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.

Condividi

Pubblicato nel numero
99 settembre 2005
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/
Articoli nella stessa serie
Ti potrebbe interessare anche