Universit` a degli Studi di Roma “La Sapienza”
Facolt` a di Ingegneria
Tesi di Laurea in
Ingegneria Informatica
Marzo, 2002
Replicazione a tre livelli: modello e prototipo
Alessandro Termini
Universit` a degli Studi di Roma “La Sapienza”
Facolt` a di Ingegneria
Tesi di Laurea in Ingegneria Informatica Sessione Invernale – Marzo, 2002
Replicazione a tre livelli: modello e prototipo
Alessandro Termini
Relatore Prof. Roberto Baldoni . . . . Co-Relatore Ing. Carlo Marchetti
. . . .
Revisore Prof. Umberto Nanni . . . .
Via Gennaro Pasquariello 8 Roma 00139
ITALIA
e-mail: [email protected] www: http://olb.studenti.eu.org
Ai miei genitori e a tutti gli amici.
Indice
Introduzione 1
1 Fondamenti di CORBA 3
1.1 Object Management Group . . . 3
1.2 L’architettura CORBA . . . 4
2 Tolleranza ai guasti 9 2.1 Introduzione alla tolleranza ai guasti . . . 9
2.2 Modelli di sistema . . . 10
2.2.1 Sistema sincrono . . . 10
2.2.2 Sistema asincrono . . . 11
2.2.3 Sistema parzialmente sincrono . . . 12
2.3 Modelli di guasto . . . 12
2.3.1 Modelli di guasto dei processi . . . 13
2.4 Caratteristiche di un sistema tollerante ai guasti . . . 15
2.4.1 Gestione della replicazione . . . 16
2.4.2 Tecniche di replicazione . . . 16
2.5 Vari approcci alla tolleranza ai guasti in CORBA . . . 18
2.5.1 Integration Approach . . . 19
2.5.2 Interception Approach . . . 20
2.5.3 Service Approach . . . 20
2.6 L’architettura FT-CORBA . . . 21
3 Replicazione a tre livelli 25 3.1 Propriet`a architetturali per la replicazione software . . . 26
i
3.2 Replicazione software a tre livelli . . . 27
4 IRL: un’architettura per la tolleranza ai guasti 31 4.1 Overview sull’architettura . . . 31
4.2 Replication Management . . . 33
4.3 Fault Notification . . . 34
4.4 Gestione degli object group . . . 34
4.4.1 Un semplice protocollo . . . 35
4.4.1.1 Protocollo del client . . . 36
4.4.1.2 Protocollo del mid-tier . . . 37
4.4.1.3 Protocollo dell’end-tier . . . 41
4.4.2 Approccio basato su un sequencer . . . 41
5 IRL: un prototipo 43 5.1 Caratteristiche dell’architettura . . . 44
5.1.1 Affidabilit`a . . . 44
5.1.2 Interoperabilit`a . . . 44
5.1.3 Trasparenza . . . 45
5.2 Componenti specifici dell’host . . . 45
5.2.1 IRLFactory . . . 46
5.2.2 LocalFailureDetector . . . 46
5.3 Componenti specifici del dominio . . . 48
5.3.1 IRLReplicationManager . . . 48
5.3.2 IRLFaultNotifier . . . 49
5.3.3 ObjectGroupHandler . . . 49
6 IRL: le performance 61 6.1 Ambiente e test preliminari . . . 61
6.2 Performance per oggetti replicati stateless . . . 64
6.3 Performance per oggetti replicati stateful . . . 66
7 Gestione delle richieste uscenti 73 7.1 Definizione del problema . . . 77
7.2 Filtraggio dei duplicati . . . 79
INDICE iii
7.3 Gestione delle richieste uscenti in IRL . . . 82
Conclusioni 84
Bibliografia 87
Elenco delle Tabelle 92
Elenco delle Figure 94
Introduzione
Con il termine middleware si identificato tutte le tecnologie software di suppor- to allo sviluppo di applicazioni distribuite. Il middleware fornisce dei servizi ad alto livello che permettono al programmatore di applicazioni distribuite di igno- rare i dettagli relativi alla comunicazione fra entit`a remote, alla loro collocazione fisica e ai loro attributi implementativi: attraverso il middleware vengono cio`e mascherate e integrate tra loro le caratteristiche eterogenee delle diverse entit`a che compongono il sistema.
Una delle pi`u diffuse infrastrutture middleware orientate agli oggetti `e CORBA, sviluppata dall’Object Management Group (OMG), un consorzio no-profit di cui fanno parte i maggiori produttori di software ed hardware mondiali. CORBA, at- traverso la definizione di una serie di interfacce di programmazione, offre una serie di strumenti standard per la comunicazione tra oggetti distribuiti. Una problem- atica particolarmente rilevante nei sistemi distribuiti `e garantire il pi`u possibile la correttezza e la continuit`a del servizio, rispetto agli utilizzatori del sistema stesso.
L’oggetto di questa tesi `e lo sviluppo di una architettura software, denomina- ta IRL, per rendere tolleranti ai guasti applicazioni distribuite basate su COR- BA. La tolleranza `e raggiunta dotando l’architettura CORBA di strumenti per realizzare delle invocazioni multiple a gruppi di oggetti, la cui interazione deve essere opportunamente gestita. Le funzioni di tolleranza ai guasti non devono essere basate su meccanismi non previsti dallo standard CORBA poich´e devono rimanere inalterate due fondamentali caratteristiche di CORBA:
• la portabilit`a: le applicazioni pienamente aderenti allo standard COR- 1
BA possono essere eseguite su qualunque implementazione CORBA senza bisogno di modifiche;
• l’interoperabilit`a: le applicazioni CORBA scritte per implementazioni diverse possono comunicare tra loro, grazie alla definizione, nella specifica CORBA, di un protocollo standard.
Negli ultimi anni sono stati sviluppati vari sistemi che forniscono il supporto ai gruppi di oggetti in CORBA. Ognuno di questi approcci tradisce, per`o, qualche aspetto della filosofia di CORBA. In particolare, lo stesso OMG ha recentemente definito e approvato la specifica di un’infrastruttura per la tolleranza ai guasti in CORBA.
L’architettura IRL intende superare alcuni dei limiti degli approcci esistenti al problema della tolleranza ai guasti in CORBA. L’architettura offre alle appli- cazioni che richiedono servizi ed oggetti CORBA, il supporto alla comunicazione affidabile con gruppi di oggetti, replicati attraverso una tecnica di replicazione attiva e residenti in un sistema asincrono. Per questo l’architettura definisce dei meccanismi per il multicast affidabile, per il rilevamento dei guasti degli oggetti e per il ripristino automatico di oggetti guasti.
Nel capitolo 1 verr`a brevemente illustrata l’architettura CORBA; nel capitolo 2 verr`a fatta una panoramica sul problema della tolleranza ai guasti, che va dalle assunzioni iniziali, fino a possibili approcci per risolvere il problema in ambito CORBA. Nel capitolo 3 verr`a illustrata l’architettura a tre livelli confrontandola essenzialmente con la classica architettura per la tolleranza ai guasti a due livel- li. Nei capitoli 4, 5, 6 verr`a presentata l’architettura denominata IRL, partendo dall’architettura a tre livelli, passando per il design e arrivando alle misure di performance effettuate su un prototipo. Infine nel capitolo 7 verr`a presentato una possibile soluzione al problema delle richieste uscenti.
Capitolo 1
Fondamenti di CORBA
1.1 Object Management Group
L’Object Management Group `e un consorzio internazionale senza fini di lucro fondato nell’aprile 1989 al fine di creare e promuovere degli standard per lo sviluppo di applicazioni distribuite mediante tecnologie software orientate agli oggetti(OO). Basandosi sull’esistenza di un’architettura standard, `e possibile ri- solvere i problemi di eterogeneit`a di piattaforme hardware e sistemi software tipici di questo settore applicativo, beneficiando, inoltre, di notevoli riduzioni nei tempi di sviluppo che si vanno ad aggiungere a quelli gi`a derivanti dall’uso di tecnologie OO.
L’OMG non si occupa direttamente di attivit`a di sviluppo software dedicandosi sostanzialmente, come detto, alla definizione di standard architetturali. Il pro- cesso di elaborazione di nuove specifiche si basa sulla partecipazione attiva dei membri.
L’OMG, infatti, richiede dei contributi tecnologici su particolari aspetti delle tec- nologie a oggetti attraverso la pubblicazione dei Request For Proposals (RFP), documenti in cui viene definito un problema e stabiliti i vincoli che devono essere rispettati nel risolverlo. I membri interessati formulano dei documenti in risposta agli RFP, nei quali descrivono dettagliatamente la loro proposta di risoluzione
3
del problema. Tutti i contributi vengono sottoposti ad una commissione tecni- ca, formata dai membri OMG con diritto di voto , che ne valuta la validit`a e la fattibilit`a, secondo un processo articolato in varie fasi. Alla fine, il risultato dell’analisi e del voto `e un documento che, racchiudendo gli aspetti delle pro- poste pervenute, che sono state giudicate migliori, descrive la specifica che verr`a adottata come standard. Sul sito Web dell’OMG ([45]) `e possibile seguire lo sta- to dei diversi RFP, dai quali si pu`o avere un’idea di quali saranno le successive evoluzioni dello standard.
1.2 L’architettura CORBA
CORBA `e un esempio di middleware orientato agli oggetti, la cui funzione `e quel- la di livello di astrazione intermedio tra le applicazioni e la rete di comunicazione.
Offre una serie di interfacce di programmazione, utilizzanti un linguaggio per la definizione di interfacce (Interface Definition Language - IDL), che implemen- tano la comunicazione tra oggetti all’interno di ambienti distribuiti eterogenei.
Le applicazioni effettuano chiamate remote ad altre applicazioni, fornitrici di servizi (che appaiono come oggetti), senza preoccuparsi di operazioni a livello di trasporto o della natura delle implementazioni. Per realizzare questo modello di interazione `e sufficiente l’architettura mostrata nella Figura 1.1.
Object Implementation
DII stub IDL interfaceORB
skeleton
Object Adapter
DSI
Object Request Broker
Client
Figura 1.1: L’architettura CORBA.
La responsabilit`a di ciascun componente `e la seguente:
• Object Implementation: definisce operazioni che implementano un’inter-
1.2. L’ARCHITETTURA CORBA 5
faccia scritta nel linguaggio CORBA IDL. L’implementazione dell’oggetto pu`o essere scritta in vari linguaggi, Java, C++, C, Ada. La Figura 1.2 illustra il diagramma relativo all’interazione tra applicazioni di linguaggio Java e C++.
File IDL
applicazione
(JAVA) stub
(JAVA) stub
(C++) skeleton
(C++) implementazione (C++)
ORB Java ORB C++
Figura 1.2: Il compilatore IDL.
• client: `e l’entit`a di programma che invoca un’operazione (obj.foo()) su un oggetto implementato; accedere ai servizi di un oggetto remoto deve essere trasparente al chiamante;
• Object Request Broker (ORB): quando il client invoca un’operazione, l’ORB `e responsabile di trovare l’implementazione dell’oggetto invocato, attivarlo trasparentemente se necessario, consegnarli la richiesta del client e restituire il risultato al client. Per individuare l’oggetto destinatario della richiesta del client, utilizza l’oggetto IOR;
• Interoperable Object Reference (IOR): `e il puntatore all’oggetto ed incapsula al suo interno informazioni (EndpointInfo ed ObjectKey) rela- tive al server. L’aspetto interessante `e il supporto per l’interoperabilit: in CORBA `e definito un formato standard per gli IOR grazie al quale questi possono essere scambiati tra diversi ORB.
• ORB interface: un ORB `e un’entit`a logica che potrebbe essere implemen- tata in vari modi (come uno o pi`u processi, tramite librerie). Per disaccop-
O bject Reference Repository ID
(s tandard) Endpoint Info
(standard) Object Key (proprietario)
Figura 1.3: L’object reference.
piare l’applicazione dall’implementazione, CORBA definisce un’interfaccia per un ORB che espone metodi per inserire argomenti in una richiesta, convertire oggetti in formato stringa;
• CORBA IDL stub e skeleton: lo stub e lo skeleton servono da tramite tra le applicazioni client e server e l’ORB. Il compilatore IDL trasforma le definizioni IDL in entit`a di un linguaggio di programmazione desiderato.
L’uso del compilatore riduce la possibilit di inconsistenza tra stub e skeleton.
• Dynamic Invocation Interface (DII): questa interfaccia consente al client di accedere direttamente al meccanismo di richieste previsto dal- l’ORB. Le applicazioni utilizzano la DII per invocare dinamicamente le operazioni sugli oggetti senza passare attraverso lo stub specifico dell’inter- faccia. Inoltre, consente al client di effettuare invocazioni di tipo “deferred synchronous” (invio e risposta sono separati) e di tipo one-way (solo invio:
il client non aspetta nessun risultato);
• Dynamic Skeleton Interface (DSI): dal lato server `e l’analoga della DII. Infatti, la DSI consente ad un ORB di consegnare una richiesta al- l’implementazione dell’oggetto, senza che questo abbia conoscenza del tipo dell’oggetto a tempo di compilazione. L’utilizzo di DSI o skeleton dal lato server `e trasparente al client;
• Object Adapter (OA): coopera con l’ORB per consegnare la richiesta all’oggetto giusto. In questo modo associa le implementazioni dell’oggetto all’ORB. Gli Object Adapter possono essere specializzati per supportare determinati stili di implementazione;
• Portable Interceptor: consente l’intercettazione trasparente e la reinvo- cazione delle richieste uscenti dal client;
1.2. L’ARCHITETTURA CORBA 7
• CORBAServices: gli Object Services sono interfacce specificate in IDL e definite in vari documenti chiamati Common Object Services Specifica- tion, che servono da supporto alle applicazioni basate su CORBA. Questi servizi includono il Name service (per la pubblicazione degli IOR), l’Event service (per la notifica asincrona di eventi), l’Interface Repository (per il reperimento a runtime delle definizioni delle interfacce IDL), l’Implemen- tation Repository (per permettere all’ORB di localizzare ed attivare le im- plementazioni di oggetti), l’Object LifeCycle service (per cancellare, creare e copiare oggetti), il TransactionService (supporto per far si che una com- putazione verifichi atomicit`a, consistenza, isolamento e persistenza di una transizione), ed altri servizi minori.
Capitolo 2
Tolleranza ai guasti
2.1 Introduzione alla tolleranza ai guasti
Scopo del presente capitolo `e quello di offrire una rassegna della letteratura riguardante il problema della tolleranza ai guasti, sia in generale sia nel ca- so specifico di CORBA. Negli ultimi anni sono state proposte varie strategie per rendere CORBA tollerante ai guasti, per cui esiste un’ampia letteratura in proposito. Inoltre, alla fine del 1998 l’OMG ha presentato una RFP (Request For Proposal), intitolata “Fault Tolerant CORBA Using Entity Redundancy”, che recentemente ha portato all’adozione di una specifica, ovvero una possibile architettura CORBA tollerante ai guasti. Di seguito vengono presentati e messi a confronto tale architettura e tutti gli approcci che l’hanno preceduta nel tempo.
Il resto del capitolo `e organizzato come segue: nella sezione 2.2 vengono de- scritti i modelli di sistema per i sistemi distribuiti; nella sezione 2.3 vengono descritti i modelli di guasto dei processi che compongono un sistema distribuito.
Nella sezione 2.4 vengono illustrate le caratteristiche fondamentali di un sistema tollerante ai guasti; nella sezione 2.5 vengono illustrati i vari approcci proposti per la tolleranza ai guasti in CORBA, e infine nella sezione 2.6 viene brevemente illustrato lo standard FT-CORBA.
9
2.2 Modelli di sistema
Le componenti principali di un sistema distribuito sono processi e canali di comunicazione, dunque il modello del sistema deve specificare formalmente:
• il numero di componenti del sistema, il tipo di computazione eseguita, le primitive a disposizione per inviare e ricevere messaggi;
• la topologia della rete di comunicazione e la portata e l’affidabilit`a dei singoli canali;
• le caratteristiche della computazione distribuita, cio`e il modo in cui essa viene rea-lizzata mediante la comunicazione e la sincronizzazione delle varie computazioni sequenziali.
Dato un sistema distribuito, una problematica calata in questo sistema si risolve stabilendo un opportuno protocollo: cio`e una serie di messaggi scambiati tra i processi; il protocollo `e dipendente dal modello di sistema adottato: in generale meno restrizioni si assumono nel modello tanto pi`u un protocollo `e complesso.
Una possibile classificazione per i modelli di sistema pu`o essere fatta attraverso le assunzioni temporali sul comportamento dei processi e dei canali di comuni- cazione.
2.2.1 Sistema sincrono
Diciamo che un sistema `e sincrono se soddisfa le seguenti propriet`a:
• esiste un upper bound conosciuto δ sul ritardo dei messaggi; consiste nel tempo necessario per mandare, trasportare e ricevere un messaggio su un link;
• ogni processo p ha un clock locale Cp con un drift rate ρ ≥ 0 conosciuto e limitato rispetto al tempo reale. Quindi per tutti i p e per tutti gli istanti di tempo t > t si ha,
(1 +ρ)−1 ≤ Cp(t) − Cp(t)
(t − t) ≤ (1 + ρ)
2.2. MODELLI DI SISTEMA 11
doveCp(t) `e la lettura del clock Cp all’istante realet.
• esistono upper bound conosciuti sul tempo richiesto da un processo per eseguire uno step.
In un sistema sincrono `e possibile misurare i time-out dei messaggi: ci`o fornisce un meccanismo per la rilevazione di guasti. Inoltre `e possibile implementare clock approssimativamente sincronizzati, cio`e clock che, oltre ad avere un drift rate limitato, soddisfano anche la seguente condizione: esiste un tale che per ogni t presi due qualsiasi processi p e q vale |Cp(t) − Cq(t)| ≤ [].
2.2.2 Sistema asincrono
Un sistema `e asincrono se non esiste alcun bound su:
• ritardo dei messaggi;
• drift del clock;
• tempo necessario per l’esecuzione di uno step.
In realt`a assumere che un sistema sia asincrono `e una non-assunzione. Ogni sistema `e asincrono: anche un sistema in cui la consegna dei messaggi `e istantanea soddisfa la definizione di sistema asincrono. Questo modello `e quello pi`u usato per diverse ragioni:
• ha una semantica semplice;
• un protocollo pensato per girare in un sistema asincrono pu`o essere usato per girare in qualsiasi sistema distribuito;
• in un sistema distribuito carichi di lavoro variabili e inaspettati sono fonti di asincronia per cui le assunzioni sincrone diventano al massimo proba- bilistiche.
2.2.3 Sistema parzialmente sincrono
I modelli sincrono e asincrono sono i due estremi di un vasto spettro di possibili modelli. Questi modelli intermedi sono chiamati sistemi parzialmente sincroni.
I sistemi parzialmente sincroni si distinguono tra loro a seconda del livello di sincronia assunto. Ad esempio i processi possono avere velocit`a limitata e clock perfettamente sincronizzati ( = 0) ma ritardo di trasmissione dei messaggi non limitato [16], oppure il ritardo dei messaggi `e limitato ma sconosciuto [17].
2.3 Modelli di guasto
I moderni sistemi di elaborazione sono costituiti da un gran numero di compo- nenti hardware e di moduli software, i quali per loro stessa natura sono soggetti a guastarsi. Un sistema distribuito ha una sua intrinseca componente di toller- anza ai guasti, proprio per il fatto che i suoi componenti sono logicamente e fisicamente collocati in zone diverse e, quindi, sperabilmente non soggetti tutti contemporaneamente alla stessa avaria; allo stesso tempo per`o introduce, rispetto a un sistema centralizzato, un’ulteriore componente soggetta ai guasti, ovvero i canali di comunicazione. Come conseguenza, si hanno:
• un maggior numero di tipologie di guasto, dovuto semplicemente a un maggior numero di combinazioni dei componenti soggetti a guasto;
• la possibilit`a di guasti pi`u maliziosi, ovvero tali da introdurre nel sistema un funzionamento apparentemente corretto, ma, in realt`a, non aderente alle specifiche1;
Un sistema tollerante ai guasti (o fault tolerant) `e un sistema progettato per comportarsi in maniera predicabile anche all’occorrenza di guasti nei suoi com- ponenti.
1Ci`o si deve al fatto che componenti “sani” possono elaborare messaggi “guasti”, cio`e deteriorati dai canali di comunicazione.
2.3. MODELLI DI GUASTO 13
2.3.1 Modelli di guasto dei processi
Di seguito vengono elencati, in primo luogo, i modelli di guasto dei processi:
• Failstop ([48]). In questo modello un processo si guasta arrestandosi e, finch´e non si arresta, si comporta secondo le specifiche. Una volta che si `e arrestato, rimane nello stato di arresto e tale fatto pu`o essere semplicemente rilevato dagli altri processi appartenenti al sistema;
• Crash ([26]). Anche in questo modello un processo pu`o guastarsi arre- standosi permanentemente e, quindi, smettendo di rispettare le specifiche, ma l’arresto del processo potrebbe non essere rilevabile dagli altri proces- si (ad esempio, in un modello asincrono). Un processo che si arresti `e comunemente detto in crash;
• Receive Omission ([47]). Un processo pu`o guastarsi ricevendo solo un sottoinsieme proprio dell’insieme dei messaggi ad esso destinati e/o arre- standosi prematuramente e definitivamente (crash). Un processo che stia omettendo di ricevere uno o pi`u messaggi `e detto in receive omission;
• Send Omission ([30]). Un processo pu`o guastarsi inviando un sottoinsieme proprio dell’insieme dei messaggi che deve realmente inviare e/o andando in crash. Anche qui un processo che sta omettendo di inviare uno o pi`u messaggi `e detto in send omission;
• General Omission ([47]). Questo modello potrebbe essere definito Send+Receive Omission: un processo pu`o gustarsi inviando/ricevendo un sottoinsieme dei messaggi in uscita/ingresso e/o arrestandosi prematuramente ovvero andando in crash.
• Bizantine Failures ([37]). `E il modello di guasto pi`u debole, un proces- so pu`o assumere qualsiasi comportamento e non rispettare affatto alcuna specifica di servizio.
Questi modelli di guasto possono essere ordinati in base alla loro gravit`a:
un modello di guasto A `e pi`u grave di un modello di guasto B se i comportamenti assunti da un processo guasto nel modello B sono un sottoinsieme proprio dei
comportamenti assunti da un processo guasto nel modello A.
Un algoritmo che tolleri guasti di tipo A, quindi, tollera anche guasti di tipo B se A `e pi`u grave di B. L’ordinamento tra modelli di guasto `e illustrato dal grafo di Figura 2.1
Receive Omission
Crash Fail Stop
Send Omission
General Omission
Byzantine
(a) Sistema asincrono
Receive Omission
Crash Fail Stop
Send Omission
General Omission
Byzantine
Timing
(b) Sistema sincrono
Figura 2.1: Tassonomia dei modelli di guasto in ambiente distribuito.
2.4. CARATTERISTICHE DI UN SISTEMA TOLLERANTE AI GUASTI 15
2.4 Caratteristiche di un sistema tollerante ai
guasti
L’obiettivo di realizzare un sistema tollerante ai guasti si raggiunge curando tre aspetti del progetto:
1. la replicazione: `e il meccanismo di base che permette di offrire continuit`a del servizio quando un componente si guasta (una replica del componente `e in grado di offrire il medesimo servizio del componente che potrebbe guas- tarsi; la tassonomia degli stili di replicazione si basa sul comportamento a tempo di esecuzione di tali repliche);
2. il rilevamento dei guasti: il sistema deve possedere meccanismi che gli consentano di discriminare la presenza di componenti guasti (per fare ci`o `e fondamentale conoscere il tipo di comportamento assunto dal componente in caso di guasto, ovvero la semantica di guasto);
3. il ripristino dei guasti: il sistema deve intervenire per riportare tut- to nelle migliori condizioni di funzionamento qualora un guasto sia rile- vato (il tipo di azione da intraprendere dipende naturalmente dal tipo di replicazione utilizzata).
La replicazione pu`o essere realizzata con diversi “stili”, la bont`a dei quali va giu- dicata sulla base di un trade-off fra complessit`a di gestione della consistenza fra le repliche e velocit`a di ripristino in caso di guasto: le relative problematiche sono di carattere teorico e ad esse sono dedicati i successivi paragrafi di questo capitolo (molte considerazioni sono tratte dal tutorial [29]).
Il rilevamento e il ripristino dei guasti, invece, dipendono fortemente dal tipo di sistema che si vuole realizzare, quindi verranno ripresi in considerazione nella discussione sui vari approcci possibili per realizzare una infrastruttura tollerante ai guasti basta su CORBA.
2.4.1 Gestione della replicazione
Idealmente, un client vorrebbe interagire con un servizio replicato come se fosse un server unico, non replicato ed ad alta disponibilit`a. Per assicurare questo `e necessario prima di tutto che ogni replica produca lo stesso risultato quando pro- cessa una stessa richiesta del client: questo requisito `e ci`o che viene formalmente definito dal criterio di consistenza di linearizzabilit`a ([32]). Da un punto di vista pratico, condizioni sufficienti per linearizzare le esecuzioni di un servizio stateful replicato sono ([29]):
• atomicit`a: se una replica server esegue un update del proprio stato, allora ogni replica alla fine esegue lo stesso update di stato o si guasta;
• ordinamento: ogni replica server non guasta esegue gli update dello stato interno nello stesso ordine.
2.4.2 Tecniche di replicazione
Nelle architetture a due livelli il client interagisce direttamente con i server repli- cati. In letteratura sono state proposte molte tecniche di replicazione (per esempio [10, 15, 22, 38, 49]) basate su assunzioni e meccanismi diversi.
Come esempio, di seguito verranno descritte brevemente le tecniche di replicazione pi`u comunemente usate.
Nella replicazione attiva un client manda una richiesta ad un insieme di repliche server deterministiche (Figura 2.2).
Ogni replica esegue la richiesta indipendentemente dalle altre e manda il risultato al client. Per assicurare la linearizzabilit`a, i client ed i server devono interagire attraverso una primitiva di total order multicast ([8]): questa primitiva assicura che tutte le repliche server processeranno le richieste nello stesso ordine prima di guastarsi. I protocolli che implementano un multicast totalmente ordinato stabiliscono l’ordine in cui i messaggi vengono consegnati alle repliche server.
2.4. CARATTERISTICHE DI UN SISTEMA TOLLERANTE AI GUASTI 17
c1
s1 s2 s3
compute(req) req
compute(req)
compute(req) result
deliver(result,req)
Figura 2.2: Replicazione Attiva.
Nella replicazione passiva una replica server (la replica che ha il ruolo di pri- mary) serve tutte le richieste dei client (Figura 2.3). Alla ricezione di una nuova richiesta, il primary la processa, produce un risultato ed aggiorna il proprio stato.
Successivamente il primary aggiorna lo stato delle altre repliche (che giocano il ruolo di backup), prima di ritornare poi il risultato al client.
c1
s1 s2 s3
compute(req) req
update
update
result
deliver(result,req)
ack ack
Figura 2.3: Replicazione Passiva.
Un modo di assicurare la linerizzabilit`a in questo caso `e quello di usare la primi- tiva di view synchronous multicast per aggiornare lo stato delle repliche backup.
L’implementazione di questa primitiva si basa sulla realizzazione di un protocollo distribuito eseguito dalle repliche server che stabilisce l’insieme di messaggi scam- biati in una “vista” ([7]).
Tutte queste tecniche di replicazione usano protocolli distribuiti di agreement:
il problema `e che questo tipo di protocolli pu`o essere adottato solo se il sistema distribuito sottoposto a guasti `e parzialmente sincrono (risultato di impossibilit`a
di Fischer, Lynch e Patterson, [25]). In questo tipo di sistemi, vengono fatte delle assunzioni temporali sulle entit`a coinvolte nei protocolli di agreement: ad esempio sul massimo ritardo nella consegna dei messaggi, o sul tempo massimo di processamento di una richiesta.
Esempi di questo tipo di modello di sistema sono modelli di sistemi asincroni
“aumentati” con failure detector di tipo unreliable ([11]) e il modello di sistema timed asynchronous ([23]).
Implementazioni delle primitive di total order e di view synchronous multicast sono rese disponibili dai cosidetti group communication toolkits, come ad esempio ISIS ([9]), TOTEM ([40]), MAESTRO/ENSEMBLE ([50]).
2.5 Vari approcci alla tolleranza ai guasti in COR-
BA
La replicazione `e basata essenzialmente sul concetto di comunicazione di gruppo:
un insieme di oggetti viene raccolto in un unico gruppo logico, rispetto al quale vengono fornite primitive di comunicazione con le quali possibile far pervenire un messaggio a tutti i membri del gruppo contemporaneamente, con diverse garanzie di ordinamento. L’object model di CORBA ([44]) specifica che un oggetto COR- BA `e accessibile tramite un object reference, che identifica sempre e solo lo stesso oggetto, in ciascuna richiesta, e che pi`u riferimenti possono puntare allo stesso oggetto. Da tale definizione emerge che CORBA si occupa solo di invocazioni remote di tipo point-to-point, quindi non viene fornito alcun meccanismo con cui il client pu`o invocare contemporaneamente pi`u oggetti usando lo stesso object reference. Negli ultimi anni sono stati sviluppati numerosi meccanismi che intro- ducono il concetto di gruppo in CORBA, dei quali si trova un ottimo compendio in [20]:
1. l’approccio di integrazione (Integration Approach) consiste nel modifi-
2.5. VARI APPROCCI ALLA TOLLERANZA AI GUASTI IN CORBA 19
care l’ORB in modo da integrare al suo interno un meccanismo di comuni- cazione di gruppo;
2. l’approccio di intercettazione (Interception Approach) consiste nell’in- tercettare i messaggi diretti all’ORB e nel multiplexarli verso gli oggetti di un gruppo facendo solitamente uso di un group communication toolkit proprietario;
3. l’approccio di servizio (Service Approach) consiste nel fornire la comuni- cazione di gruppo definendo un nuovo CORBA service.
2.5.1 Integration Approach
L’approccio di integrazione (Figura 2.4) estende le funzionalit`a dell’ORB con l’inserimento di un toolkit per la comunicazione di gruppo. L’ORB si occupa direttamente degli object groups e dei riferimenti agli object groups. Le richi- este CORBA sono passate ad un toolkit per la comunicazione di gruppo (group communication toolkit [18]) che effettua il multicast verso i server replicati, uti- lizzando un meccanismo proprietario.
Modi fied ORB
Multicast Group Toolkit
Client Object Object
Replica Object Replica G
r o u p
Figura 2.4: Approccio di integrazione per la tolleranza ai guasti in CORBA.
L’approccio `e chiamato di “integrazione” poich´e il gruppo toolkit `e integrato nel- l’ORB. I sistemi che attualmente sfruttano questo approccio sono Orbix+Isis ed Electra ([36]).
2.5.2 Interception Approach
L’approccio ad intercettazione (Figura 2.5) presuppone che l’ORB non abbia cog- nizione della replicazione. Le richieste ORB sono intercettate in maniera traspar- ente sia lato client che lato server, usando meccanismi di intercettazione di basso livello. A questo punto, la richiesta intercettata viene passata a un group com- munication toolkit che effettua il multicast verso il gruppo di interesse.
Unmodi fied ORB
Multicast Group Toolkit
Client Object Object
Replica Object Replica G
r o u p
Interceptionlayer
Figura 2.5: Approccio di intercettazione per la tolleranza ai guasti in CORBA.
Tale approccio non richiede la modifica dell’ORB come il precedente approccio di integrazione, ma per intercettare le richieste fa affidamento su meccanismi specifici del sistema operativo. Un esempio di tale approccio `e il sistema Eternal ([41]), sviluppato nell’Universit`a della California a Santa Barbara, che si basa sul- l’intercettazione dei messaggi prima che questi raggiungano il livello di trasporto TCP/IP.
2.5.3 Service Approach
L’approccio di servizio (Figura 2.6) fornisce un supporto esplicito all’astrazione di gruppo mediante la realizzazione di un nuovo CORBA service. A differenza del- l’approccio di integrazione che estende l’ORB con meccanismi di comunicazione proprietari, in questo caso va semplicemente specificato un nuovo servizio COR- BA mediante interfacce IDL, per cui non c’`e nessuna dipendenza da un particolare ORB o da un particolare linguaggio implementativi. L’ORB rimane ignaro della nozione di gruppo e il servizio pu`o essere utilizzato con qualsiasi implementazione
2.6. L’ARCHITETTURA FT-CORBA 21
CORBA compliant.
ORB
Client Object Object
Replica Object Replica G
r o u p
Trans action Notificati on Group
Communication
Common O bject Ser vic e
Figura 2.6: Approccio di servizio per la tolleranza ai guasti in CORBA.
Un esempio importante di sistema basato sull’approccio al servizio l’Object Group Service (OGS), sviluppato dall’`Ecole Polytechnique de Lausanne, Svizzera ([20, 21]) , che si basa su una serie di sottoservizi ciascuno dei quali si configura come un servizio indipendente dall’altro.
La Tabella 2.1 fornisce in sintesi un confronto tra i vari approcci sopra descritti per aumentare CORBA con la nozione di gruppo. Le caselle lasciate in bianco indicano che la relativa propriet`a `e solo parzialmente soddisfatta.
Approcci per la FT
Integration Interception Service
Trasparenza SI SI
Interoperabilit`a SI SI
Portabilit`a NO SI
CORBA compliance NO SI SI
Tabella 2.1: Confronto fra i vari approcci usati per la FT.
2.6 L’architettura FT-CORBA
La specifica FT-CORBA ([43]) raggiunge la tolleranza ai guasti definendo un supporto per la ridondanza di oggetti CORBA, per il rilevamento dei guasti e per
il recovery dai guasti.
Le repliche di oggetti CORBA sono dislocate su diversi host di un dominio di tolleranza ai guasti2 (FT-domain). Le repliche di un oggetto sono chiamate membri e sono riunite in un object group, cio`e un elemento logico usato per fa- cilitare l’indirizzamento degli oggetti replicati ([6]) e che permettono ai client di accedere trasparentemente ai membri dell’object group come se quest’ultimo fosse un oggetto singleton, non replicato e ad alta disponibilit`a. Se l’oggetto replicato
`e stateful allora deve essere rispettata la strong replica consistency3 dello stato dei membri dell’object group.
Le modifiche e le estensioni pi`u importanti apportate allo standard CORBA riguardano l’indirizzamento degli object group, la definizione di una nuova se- mantica di failover per il client e nuove tecniche e componenti architetturali per la gestione della replicazione, gestione dei guasti e la gestione del ripristino dai guasti.
Indirizzamento degli object group. Per identificare ed indirizzare gli ob- ject group, la specifica FT-CORBA introduce gli Interoperable Object Group Ref- erences (IOGRs). Un IOGR `e un Interoperable Object Reference (IOR, [44]) CORBA, composto da profile multipli, ognuno dei quali pu`o indirizzare:
• un membro dell’object group, per esempio nel caso di replicazione passiva o stateless;
• un gateway che gestisce l’accesso ai membri dell’object group, ad esempio nel caso di replicazione attiva.
Gli IOGR sono usati dagli ORB dei client per accedere trasparentemente agli object group.
2Un dominio di tolleranza ai guasti `e un insieme di host interconnessi da una rete di computer non partizionabile.
3Formalmente, la strong replica consistency corrisponde alla linearizzabilit`a delle richieste eseguite dagli oggetti replicati.
2.6. L’ARCHITETTURA FT-CORBA 23
Estensione della semantica di failover di un client CORBA. Per fornire alle applicazioni la trasparenza sulla replicazione e sui guasti, un ORB compliant con la specifica FT-CORBA deve implementare le tecniche della reinvocazione trasparente e della redirezione:
• quando un ORB riceve una richiesta da un’applicazione client, la identifi- ca univocamente attraverso un FTRequestServiceContext e manda la richi- esta all’object group indirizzato dall’IOGR (o meglio dai profile presenti nell’IOGR);
• quando un ORB riceve una failover condition, ad esempio una TRANSIENT o NO RESPONSE exception, viene usato un altro profilo dell’IOGR per eseguire di nuovo la richiesta fino a quando non viene ricevuto un risultato oppure scade il request expiration time associato alla richiesta.
Gestione della replicazione. Include meccanismo per la creazione e la ges- tione degli object group e dei membri di un object group: il componente de- nominato ReplicationManager `e responsabile di queste attivit`a. In particolare, quando un’applicazione client richiede la creazione di un object group, il Replica- tionManager sfrutta le local factory (messe a disposizione dagli sviluppatori delle applicazioni) per creare i membri dell’object group, per reperire gli object refer- ence dei nuovi oggetti creati, e restituisce alla fine la reference dell’object group.
Il ReplicationManager permette di selezionare la tecnica di replicazione per un object group e di scegliere se la consistenza di oggetti stateful deve essere gestita dall’applicazione stessa o dall’infrastruttura.
Gestione dei guasti. Consiste nel rilevamento dei guasti dei membri di un ob- ject group, nella creazione, notifica e analisi dei fault report relativi ai guasti rile- vati. Queste attivit`a devono essere implementate rispettivamente dai componenti denominati FaultDetectors, FaultNotifier e FaultAnalyzer. Un oggetto replicato pu`o essere monitorato da un FaultDetector se implementa l’interfaccia PullMonitorable.
Il FaultNotifier `e basato sul paradigma di funzionamento publish-and-subscribe. Il FaultNotifier riceve i fault report dai vari FaultDetector (i publishers) propaga
queste notifiche di guasti al ReplicationManager e ad altri client interessati (i subscribers).
Gestione del ripristino dai guasti. E basata su due attivit`` a, chiamate log- ging e recovery, che sfruttano due interfacce definite dalla specifica (Check- pointable and Updateable). Il meccanismo di logging periodicamente memorizza in un log informazioni riguardanti gli oggetti (ad esempio gli update dello sta- to dei membri, le richieste servite, i risultati restituiti, e l’expiration time della richiesta), mentre il meccanismo di recovery recupera queste informazioni dal log quando, ad esempio, si aggiunge un membro ad un object group esistente, ed `e quindi necessario settarne lo stato interno per mantenere la consistenza del gruppo.
Un dominio di tolleranza ai guasti deve contenere una istanza logica del Repli- cationManager e del FaultNotifier. I FaultDetectors invece sono dislocati su tutto il dominio per rilevare i guasti degli oggetti monitorabili4. Questa infrastruttura software `e comunemente denominata infrastruttura tollerante ai guasti.
Lo standard FT-CORBA `e il risultato di ricerche nel campo dei sistemi dis- tribuiti tolleranti ai guasti e nel campo della computazione distribuita ad oggetti (DOC - Distributed Object Computing). I principali contributi sono stati dati dai seguenti sistemi: Isis+Orbix e Electra ([36]), OGS ([20, 21]), AQuA ([14]), DOORS ([12]) e Eternal ([41]).
4Cio`e che implementano l’interfaccia PullMonitorable.
Capitolo 3
Replicazione a tre livelli
L’idea che sta alla base della replicazione software `e quella di replicare server su host differenti connessi tra loro tramite una rete di comunicazione, in modo da permettere ad un client di usufruire di un servizio connettendosi a diverse repliche server. Queste tecniche di replicazione software sono realizzate tipicamente in un approccio two-tiers (2T): un client (client-tier) interagisce direttamente con un insieme di repliche server che offrono lo stesso servizio (end-tier).
Se il servizio fornito `e stateless1, migliorare la disponibilit`a del servizio si riduce nel lasciare che il client reinvochi trasparentemente la richiesta su tutte le repliche server, prima di ricevere un’eccezione. Se invece il servizio `e stateful, c’`e il prob- lema di garantire la consistenza tra gli stati delle repliche a fronte di guasti.
La replicazione attiva ([49]), passiva ([10]), semi-passive ([15]) e “a quorum”
([27, 38]) sono le tecniche 2T pi`u comuni per aumentare la disponibilit`a di server stateful. Il risultato di impossibilit`a di Fischer, Lynch e Patterson (FLP impos- sibility result [25]) rende impossibile realizzare server stateful replicati su sistemi asincroni, come ad esempio Internet. Al contrario, si pu`o notare che le repliche di un servizio stateless possono essere collocate in un sistema asincrono, visto che non necessitano di un protocollo di agreement.
1Il risultato di una richiesta dipende solo dalla richiesta da processare.
25
Il capitolo `e strutturato come segue: nella sezione 3.1 verrano illustrate due pro- priet`a architetturali che definiscono l’ambito in cui i processi di un sistema dis- tribuito possono essere posizionati; nella sezione 3.2 viene proposto l’approccio a tre livelli per la replicazione, con lo scopo di superare alcuni limiti delle classiche tecniche di replicazione.
3.1 Propriet` a architetturali per la replicazione
software
Il mantenimento della consistenza dello stato di repliche di oggetti stateful `e un requisito fondamentale per la replicazione, ma si possono definire altre propriet`a architetturali per la replicazione che riguardano sia i client che le repliche e che si calano nella natura del modello di sistema in cui queste entit`a vivono:
P1 (Client/Server-Asynchrony): un client (e rispettivamente un server) gira- no in un sistema distribuito senza alcuna assunzione temporale (per esempio un sistema distribuito asincrono);
P2 (Client-Autonomy): un client non deve intervenire in nessun protocollo distribuito di coordinazione che coinvolga altri client e/o repliche server con lo scopo di mantenere la consistenza delle repliche del servizio.
La propriet`a P1 implica che i client e le repliche server di servizi stateful replicati possono essere distribuite su sistemi asincroni (come ad esempio Internet), nello stesso modo fatto per servizi stateless replicati. Invece la propriet`a P2 perme- tte di implementare client molto leggeri (thin client), in modo da aumentare lo spettro di dispositivi su cui questi client possono girare (ad esempio cellulari, PDA, etc.).
Si pu`o facilmente notare che le tecniche di replicazione precedentemente citate, non rispettano la propriet`a P1, in quanto impongono ai server (ed alcune volte ai client) di girare in un sistema parzialmente sincrono. D’altra parte, in schemi di replicazione attiva implementati attraverso la primitiva di total order multicast,
3.2. REPLICAZIONE SOFTWARE A TRE LIVELLI 27
in cui `e il client che stabilisce l’ordine in cui verranno consegnati i messaggi (per esempio [19]), anche la propriet`a P2 non `e soddisfatta.
3.2 Replicazione software a tre livelli
La replicazione software a tre livelli (three-tier replication - 3T) include la logica di replicazione in un “livello software intermedio” (mid-tier ) posto tra client e server replicato, che ha il compito di assicurare la linearizzabilit`a all’esecuzioni delle repliche del servizio replicato (end-tier, Figura 3.1).
mid-tier end-tier
client tier C1 C2
Cm
Replication Logic
R1 R2
Rn
Sistema Distribuito Asincrono
Sistema Distribuito Parzialemente Sincrono
Sistema Distribuito Aincrono
Figura 3.1: Architettura base a 3 livelli.
In questa architettura, un client manda la richiesta al mid-tier, il quale la in- oltra alle repliche server rispettando la logica di replicazione implementata. Le repliche dell’end-tier processano la richiesta, mandando il risultato dell’operazione invocata al mid-tier, che alla fine la restituisce al client. In Figura 3.2 `e mostrata una semplice interazione client/server nel caso di end-tier replicato attivamente.
Per assicurare la terminazione dell’interazione client/server anche in presenza di guasti, i processi del mid-tier dovranno essere tolleranti ai guasti: in parti- colare, se la replica del mid-tier che sta gestendo l’interazione client/server si guasta, un’altra replica dovr`a terminare l’interazione, allo scopo di assicurare la consistenza delle repliche dell’end-tier, anche a fronte di guasti. In generale
C1 C2
M1
M2
M3
R1 R2 R3
Client-tier
Mid-tier
End-tier
richiesta risultato
risultato richiesta
Figura 3.2: Scambio di messaggi per end-tier replicato attivamente.
questo implica che il mid-tier dovr`a mantenere uno stato (replicato): questo sta- to potrebbe includere informazioni sull’ordinamento delle richieste del client, il processo del mid-tier responsabile dell’interazione tra client e server, etc.
Inoltre, c’`e la necessiat`a in generale di un protocollo distribuito di agreement per le repliche del mid-tier: questo implica l’assunzione di sistema parzialmente sincrono solo ed esclusivamente per il mid-tier.
Questo approccio soddisfa entrambe le propriet`a definite nella sezione precedente (sezione 3.1):
• un client interagisce direttamente solo col mid-tier, l’unico responsabile del mantenimento della consistenza dell’end-tier; quindi la propriet`a P2 (Client-Autonomy) `e soddisfatta;
• le repliche server e i client non necessitano di nessun protocollo di agreement;
i client hanno solo bisogno di un semplice meccanismo di ritrasmissione per far fronte a guasti del mid-tier o a ritardi nella consegna dei messag- gi. Analogalmente, le repliche server implementano semplici funzionalit`a aggiuntive (ad esempio filtraggio dei duplicati), oltre a quelle offerte dal servizio messo a disposizione; la propriet`a P1 (Client/Server-Asynchrony)
`
e soddisfatta.
3.2. REPLICAZIONE SOFTWARE A TRE LIVELLI 29
C’`e da sottolineare il fatto che l’approccio a tre livelli produce una netta sepa- razione tra la gestione della replicazione e il reale servizio implementato. Rispetto all’approccio classico a due livelli si possono individuare i seguenti vantaggi:
• un client (ma anche un server) potrebbe comunicare con le entit`a del mid- tier con interazioni point-to-point, seguendo cos`ı il semplice paradigma di interazione asincrona richiesta/risposta;
• disaccoppiando la gestione dell replicazione dal servizio, c`e la possibilit`a di modificare lo stile di replicazione senza impattare sul client. Per esempio si potrebbe modificare “al volo” lo stile di replicazione dell’end-tier, passando da replicazione attiva a replicazione passiva ([1]);
• le repliche dell’end-tier sono poco accoppiate (loosely coupled): le repliche non scambiano messaggi fra loro; inoltre, le repliche server potrebbe non aver bisogno di sapere quale schema di replicazione `e implementato dal mid-tier;
• l’approccio a tre livelli limita l’uso di “group communications toolkit” solo alle entit`a del mid-tier.
Capitolo 4
IRL: un’architettura per la
tolleranza ai guasti
4.1 Overview sull’architettura
L’architettura tollerante ai guasti denominata IRL (Interoperable Replication Logic) utilizza la replicazione a tre livelli per aumentare la disponibilit`a di ogget- ti stateful deterministici sviluppati sulla piattaforma CORBA ([44]). IRL mette a disposizione degli sviluppatori di applicazioni CORBA tolleranti ai guasti mec- canismi per la rilevazione di guasti e per la gestione della replicazione attraverso interfacce standard definite nella specifica FT-CORBA ([43]).
La scelta di realizzare il prototipo basandoci sullo standard FT-CORBA si basa essenzialmente su due considerazioni:
• la specifica FT-CORBA `e lo standard pi`u conosciuto per la tolleranza ai guasti nell’ambiente distribuito ad oggetti;
• la specifica FT-CORBA “aumenta” i client solo con un semplice meccanis- mo di ritrasmissione e redirezione, che si adatta al modello di client ipotizza- to per lo schema di replicazione a tre livelli. Questo significa che un client compliant con la specifica FT-CORBA soddisfa la propriet`a denominata Client-Autonomy, definita nella sezione 3.1.
31
L’infrastruttura denominata IRL corrisponde al mid-tier dell’architettura a tre livelli per la replicazione software di oggetti CORBA stateless e stateful. La Figura 4.1 mostra i principali componenti dell’infrastruttura.
Per salvaguardare la portabilit`a e l’interoperabilt`a dell’infrastruttura, cos`ı come mostrato nella Figura 4.1, la comunicazione tra i client, le entit`a del mid-tier e i membri degli object group (cio`e le repliche server dell’end-tier) `e realizzata attraverso le invocazioni standard di CORBA1: in particolare, i client di object group stateful interagiscono col componente dell’architettura denominato Object- GroupHandler che gestisce l’interazione con i membri degli object group; nel caso di server stateless replicati, i client si connettono direttamente con uno dei mem- bri dell’object group.
Object Request Broker
Client Obj Obj Obj
RM RM RM
FN FN FN OGH
OGH OGH
mid-tier
STATEFUL Object Group
Client Obj Obj Obj
STATELESS Object Group
client-tier end-tier
Sitema Distribuito Asincrono
Sistema Distribuito Parzialmente Sincrono
Sitema Distribuito Asincrono OGH
RM FN
IRL Object Group Handler IRL Replication Manager
IRL Fault Notifier
Intra-component message bus
Figura 4.1: L’architettura di IRL
Per assicurare la terminazione dell’interazione client/server e i servizi di gestione e controllo, i componenti di IRL, denominati ObjectGroupHandler, IRLReplication- Manager e IRLFaultNotifier sono replicati, come mostrato in Figura 4.1.
Le repliche di tutti i componenti di IRL girano un in ambiente parzialmente
1IRL usa solo meccanismo standard definiti da CORBA, come ad esempio SSI (Static Skele- ton Interface) e DSI (Dynamic Skeleton Interface), SII (Static Invocation Interface) e DII (Dynamic Invocation Interface), i Portable Interceptors, il Naming Service e l’Interface Repository
4.2. REPLICATION MANAGEMENT 33
sincrono; si pu`o notare che sia i client che i membri degli object group non neces- sitano di nessuna assunzione temporale: quindi IRL soddisfa la propriet`a definita nella sezione 3.1 denominata Client/Server-Asynchrony. In altre parole, tutte le assunzioni di sincronia necessarie per mantenere la consistenza dei membri degli object group sono confinate nel mid-tier; inoltre le repliche dei componenti di IRL interagiscono tra loro attraverso un intra-component message bus (non nec- essariamente un ORB) basato essenzialmente su TCP/IP.
Nel seguito, saranno presentate delle brevi descrizioni dei componenti di IRL:
questa descrizione sar`a funzionale, nel senso che sar`a indipendente dalla tecni- ca adottata per replicare i componenti di IRL, che sar`a introdotta nel prossimo capitolo.
4.2 Replication Management
Il componente IRLReplicationManager implementa l’interfaccia ReplicationManager definita nella specifica FT-CORBA. In particolare, quando viene richiesto ad RM di creare nuovi object group, questo componente crea, attraverso le local factory messe a disposizione dagli sviluppatori dei server, i nuovi membri degli object group, restituendo poi il riferimento all’object group appena creato; l’interazione tra RM e le local factory `e definita dalla specifica FT-CORBA attraverso l’inter- faccia GenericFactory.
Il replication manager di IRL permette la gestione di object group stateless e stateful con consistenza e membership controllata sia da una applicazione che dall’infrastruttura stessa. Nel caso in cui la consistenza del gruppo sia controlla- ta dall’infrastruttura, il componente si occupa della creazione delle repliche degli ObjectGroupHandler (vedi sezione 4.4 per i dettagli).
4.3 Fault Notification
Come definito nella specifica FT-CORBA, il componente denominato IRLFault- Notifier:
• riceve dagli IRL LocalFailureDetector (LFD)2 i report riguardanti i guasti di oggetti;
• riceve sottoscrizioni dai client per le notifiche di guasti.
Subito dopo aver ricevuto un fault report da un failure detector, il fault notifier di IRL lo inoltra al replication manager e ai client interessati. Oltre a questo, il fault notifier riceve heartbeat dai vari LFD del domino, per monitorare eventuali guasti degli host: non appena rileva3 il guasto di un host, FN crea un fault report che sar`a mandato al replication manager e a tutti i client che si soni iscritti per gli oggetti residenti sull’host guasto.
4.4 Gestione degli object group
Il componente ObjectGroupHandler `e associato ad ogni object group stateful : memorizza le informazioni riguardanti i membri degli object group, ed `e inoltre responsabile di assicurare la strong replica consistency dello stato dei membri degli object group.
Questo componente realizza il mid-tier di architettura a tre livelli. Sfruttando gli IOGR e i meccanismi DII e DSI di CORBA, l’Object Group Handler:
• accetta tutte le connessioni dai client;
• riceve tutte le richieste dirette all’object group che gestisce;
• impone a queste richieste un ordine totale;
2Compliant con i FaultDetector della specifica FT-CORBA
3Il modo in cui FN “decide” che un host `e guasto dipende da vari fattori, come ad esempio il modello di sistema ipotizzato; nel Capitolo 5 verr`a specificato il meccanismo di rilevamento dei guasti.
4.4. GESTIONE DEGLI OBJECT GROUP 35
• inoltra le richieste a tutti i membri degli object group;
• raccoglie i risultati provenienti dai membri degli object group e li restituisce al client.
Client
MemberOG 1
MemberOG 3
MemberOG 2
OGH Object Group
Figura 4.2: Schema di funzionamento del componente ObjectGroupHandler.
Si pu`o notare che i client non appartengono a nessun tipo di gruppo, e che si connettono ad OGH diversi per accedere ad object group diversi4.
L’attivit`a principale svolta dall’ObjectGroupHandler `e quella di ordinare le richi- este provenienti dai client; in fase di analisi sono stati sviluppati due differenti protocolli di ordinamento: uno che si basa su forti assunzioni di sincronia, e per questo pi`u facilmente realizzabile, che sar`a poi illustrato in dettaglio nella sezione 4.4.1, e uno pi`u complesso ([4]) che permette di rilassare le forti assunzioni fatte in precedenza.
4.4.1 Un semplice protocollo
Il primo protocollo proposto si basa essenzialmente su forti assunzioni di sincronia del mid-tier; il sistema distribuito considerato `e asincrono e composto da un insieme finito di processi che comunicano tramite scambio di messaggi su canali di comunicazione affidabili. I processi sono soggetti a guasti di tipo crash (vedi sezione 2.3.1); si possono individuare tre insiemi distinti di processi:
4Questo favorisce la scalabilit`a dell’approccio.
• C ∈ {c1, c2, c3, c4, . . . , cn}: insieme di processi client;
• A ∈ {a1, a2, a3, a4, . . . , ak}: insieme delle repliche del mid-tier;
• E ∈ {e1, e2, e3, e4, . . . , em}: insieme delle repliche server.
Le repliche del mid-tier sono stateless rispetto alla richiesta che il client vuole invocare sui server replicati: cio`e, le richieste dei client vengono solo inoltrate ai server replicati; come diretta conseguenza di ci`o si `e scelto di replicare i processi dell’end-tier con uno schema di replicazione passiva; le richieste vengono proces- sate dal mid-tier una alla volta: le richieste ricevute dal primary vengono inserite in una coda locale al processo. Ad ogni richiesta inoltrata viene associato un numero di sequenza che verr`a usato nel caso il primary si guasti. Per evitare che gli end-server processino anche richieste pervenute con notevole ritardo (cio`e relative a vecchi primary ormai guasti), ogni messaggio include l’identit`a del pri- mary che lo ha spedito; sulle repliche verr`a di volta in volta aggiornata l’identit`a del primary attivo in un determinato istante.
c1
r1
a2
a3 r2
a1
r3
r5
r4 coda di
richieste
Figura 4.3: Interazione client/server.
Il protocollo si compone essenzialmente di tre parti: una per il client, una per il mid-tier e una per l’end-tier.
4.4.1.1 Protocollo del client
L’invocazione di una operazione da parte di un client avviene attraverso l’invo- cazione della primitiva issue (Figura 4.4): questa primitiva prende come parametro di input la richiesta destinata ai server replicati, e ritorna il risultato a tale richies- ta. Il client ritrasmetter`a la richiesta a tutti i processi del mid-tier, fino a quando
4.4. GESTIONE DEGLI OBJECT GROUP 37
Class ClientProtocol()
1 array of AppServer alist := theAppServers;
2 Integer i := 1;
3
4 Result issue(Request request) 5 AppServer a;
6
7 begin
8 while true do 9 a := alist[i];
10 send [Request, < c id, req id, request >] to a;
11 when ((receive [Result, res] from a) or (exception)) do 12 if (not exception)
13 then return (res);
14 else i := (i + 1) mod|alist|;
15 end
Figura 4.4: Pseudo codice del protocollo lato client.
non ricever`a un risultato: solo il primary per`o inoltrer`a la richiesta alle repliche dell’end-tier, mentre le altre repliche risponderanno con un’eccezione, che causer`a una reinvocazione da parte del client; l’ipotesi di avere almeno una replica del mid-tier corretta assicura che il processo di reinvocazione prima o poi finir`a con la consegna del risultato al client. Le eccezioni dovute alla richiesta sono state modellate come dei risultati da restituire comunque al client, mentre eventuali timeout sulla connessione tra client e mid-tier oppure eccezioni dovuti a guasti del mid-tier, sono state modellate come quelle eccezioni che causeranno una rein- vocazione della richiesta su un’altro processo del mid-tier.
Si pu`o notare che il protocollo del client implementa un semplice meccanismo di ritrasmissione e redirezione: cio`e `e soddisfatta la propriet`a Client-Autonomy definita nella sezione 3.1.
4.4.1.2 Protocollo del mid-tier
Il mid-tier adotta uno schema di replicazione passiva: una replica degli Ob- jectGroupHandler processa tutte le richieste occupandosi di mantenere ordine
e atomicit`a. Per assicurare queste due propriet`a, il primary processa le richi- este una alla volta: quando il client invoca una richiesta sui server, il primary si occupa di inoltrarla a tutte le repliche server, attendendo il risultato da tutte le repliche; restituito poi il risultato al client, processa una nuova richiesta.
C1
R2 C2
req1
req2
R1 OGH1 OGH3 OGH2
R3
req1 req2
Figura 4.5: Interazione client/server senza guasti.
Riferendoci alla Figura 4.5, quando il client C1 invoca la richiesta req1, il pri- mary dell’ObjectGroupHandler la inoltre a tutte le repliche del servizio; quando il client C2 invoca la richiesta req2, questa viene accodata dall’ObjectGroupHandler primary per essere processata quando tutte le repliche server hanno restituito la risposta alla richiesta req1.
La forte assunzione fatta sul sistema consiste nell’uso di failure detector per- fetti : cio`e caratterizzati dalle propriet`a di “accuratezza forte” (strong accuracy) e “completezza forte” (strong completeness) definite da [11]; in pratica l’ipotesi fatta `e che non vengono commessi errori nella rilevazione dei guasti, sia delle repliche dell’mid-tier sia di quelle dell’end-tier.5 Se una replica dell’end-tier si guasta il primary che sta processando la richiesta, non aspetter`a il risultato da
5Questo tipo di rilevazione dei guasti pu`o essere fatta rispettare facendo girare le repliche monitorate in un sistema con un determinato tasso di sincronia (es. una rete a traffico control- lato) o in un sistema parzialmente sincrono (come il “timed asynchronous system”) con l’ausilio di hardware watchdogs ([24]).
4.4. GESTIONE DEGLI OBJECT GROUP 39
tale replica, visto che sicuramente il processo in questione `e guasto.
C1
R2
req1
R1 OGH1
OGH3 OGH2
R3
crash di R3
req1
rilevamento del guasto
FN
Figura 4.6: Interazione client/server con guasto di una replica dell’end-tier.
La Figura 4.6 mostra come il primary si sblocchi non aspettando pi`u il risultato da una replica guasta. Quando il FaultNotifier rileva che una replica `e guasta, lo comunica a tutti i processi del mid-tier; se il primary `e bloccato in attesa del risultato da quella replica, si sboccher`a restituendo al client il risultato ottenuto dalle altre repliche.
Oltre ai guasti delle repliche server, gli OGH gestiscono eventuali guasti del pri- mary: in questo caso `e necessario (i) stabilire un protocollo per l’elezione del nuovo primary (ii) effettuare una fase di recovery per ripristinare la consistenza del gruppo di repliche dell’end-tier (eventualmente violata).
L’elezione del nuovo primary avviene sfruttando l’ipotesi di accuratezza dei fail- ure detector: quando viene notificato il guasto di una replica degli OGH, ogni replica del mid-tier verifica se deve diventare primary o no; in particolare la prima replica del mid-tier non guasta diventer`a il nuovo primary (Figura 4.7) dopo aver effettuato il recovery delle repliche dell’end-tier.