Supporto per servizi di File Hosting

Transcript

Supporto per servizi di File Hosting
Supporto per servizi di File Hosting
Progetto per il corso di Reti di Calcolatori LS – a.a 2005-2006
Valerio Guagliumi – 0000236769
Abstract
Questa relazione descrive il progetto realizzato di un sistema di supporto allo sviluppo di servizi di
File Hosting affidabili e con bilanciamento del carico. Il sistema è indipendente dal contesto
applicativo e dai protocolli utilizzati e propone una soluzione scalabile e con overhead limitato, che
si adatta facilmente ai requisiti di progetto.
1. Introduzione
La rapida espansione delle reti di calcolatori su larga scala negli ultimi decenni, ha incentivato molti
fornitori di servizi a studiare e inventare nuove forme di comunicazione per venire incontro ai
bisogni dei clienti.
Tra le tecnologie di servizio sviluppatesi, molte sono nate per rispondere all’esigenza degli utenti di
comunicare tra loro e condividere risorse e dati; queste tecnologie seguono quindi un modello di
comunicazione consumer-to-consumer, che apre canali tra gli utenti stessi, piuttosto che tra
l’erogatore ed il consumatore di un servizio.
Oltre ai sistemi di messaggistica, che permettono agli utenti di inviare e ricevere informazioni sotto
forma di messaggi testuali, un’altra branca di servizi di questo tipo è costituita dai sistemi di
scambio di file, nei quali vengono trasmesse informazioni sotto forma di documenti generici.
Una possibile realizzazione di servizi di questo tipo è quella del File Sharing: applicazioni
distribuite tramite le quali gli utenti possono scambiare file in
maniera sincrona e tipicamente solo uno-a-uno; prevedono cioè un
solo mittente ed un solo ricevente, i quali devono essere entrambi
presenti contemporaneamente per tutta la durata della trasmissione.
Altri servizi, che prendono il nome di File Hosting, permettono una
maggiore flessibilità nella modalità di comunicazione tra utenti,
fornendo supporto allo scambio di file in maniera asincrona e con
più possibili riceventi.
In questi sistemi le entità che desiderano partecipare alla
comunicazione assumono il ruolo di clienti di un servitore che
espone delle operazioni di Upload e Download, che corrispondono rispettivamente a operazioni di
scrittura e lettura di un file su un dispositivo di memorizzazione permanente.
La qualità dei sistemi di file hosting è legata in gran parte alle loro
proprietà di availability (la garanzia che il servizio sia sempre
disponibile per eseguire upload e download) e di correctness (la
certezza che il contenuto dei file letti dal sistema sia sempre lo
stesso memorizzato all’atto della scrittura); questo progetto nasce
con l’idea di fornire un supporto per la realizzazione di sistemi di
file hosting fault-tolerant e scalabili che siano dotati di queste
caratteristiche.
2. Architettura del sistema
La tecnica comunemente adottata per ottenere garanzie di correttezza in un servizio di File Hosting
è l’uso di risorse replicate, che significa mantenere più copie dello stesso file su diversi servitori, e
verificarne all’occorrenza la consistenza confrontandole tra loro.
La replicazione dei file permette inoltre di fornire il servizio anche in caso di caduta di uno o più dei
nodi, purchè sia attivo almeno uno dei nodi in grado di ricevere ed eseguire le operazioni di upload
e download.
Un problema con cui si scontrano spesso i servizi di File Hosting è costituito dalle situazioni di
congestione in cui si vengono a trovare i nodi servitori nel caso in cui debbano servire un numero di
operazioni superiore a quanto è possibile secondo le loro capacità computazionali, oppure una volta
esaurito lo spazio disponibile per la memorizzazione dei file.
Per queste ragioni il sistema è organizzato in gruppi di replicazione tra loro indipendenti: tutti i nodi
che appartengono ad uno stesso gruppo replicano ciascuno lo stesso insieme di file; un nodo
speciale, detto Proxy, si occupa di ricevere ciascuna richiesta proveniente da un cliente e delegarla
ad uno dei nodi del gruppo di replicazione a cui il file richiesto è univocamente assegnato.
La redirezione delle richieste da parte del Proxy verso un nodo delegato ad eseguire l’operazione,
scarica il Proxy da ogni responsabilità sull’effettivo trasferimento (il quale rischierebbe altrimenti di
congestionarsi facilmente e fare da “collo di bottiglia” per il sistema), e permette di implementare
politiche di Load Balancing per suddividere tra i nodi di ogni gruppo di replicazione le risorse
computazionali e la banda, e, allo stesso tempo, partizionare sui diversi gruppi la capacità di
memoria richiesta.
Il Proxy ha a sua disposizione ad ogni istante le informazioni su quali nodi di ciascun gruppo sono
attivi; se almeno un nodo per ogni gruppo è attivo, il sistema è complessivamente in grado di
erogare il servizio, altrimenti il Proxy nega al client la possibilità di eseguire operazioni di upload o
download.
Il progetto, sviluppato in Java, fornisce un supporto allo sviluppo di sistemi di File Hosting.
La comunicazione tra il Proxy e i nodi di replicazione è implementata con Socket TCP, mentre il
protocollo e i metodi di comunicazione tra il client e i diversi nodi del sistema, che sono variabili
strettamente legate al contesto applicativo, non sono specificati.
Ad esempio, nel caso di servizio di Web File Hosting, queste comunicazioni dovrebbero avvenire
tramite HTTP, e i Proxy e i nodi di replicazione comunicherebbero con i clienti tramite Web Server.
Sono quindi fornite le interfacce da implementare per definire protocolli di comunicazione,
politiche di scelta dei nodi per servire le richieste, codifiche da applicare sui messaggi di delega che
il Proxy indirizza ai nodi di replicazione tramite la redirezione dei client, e altri parametri che
regolano il funzionamento del sistema.
3. Gruppo di replicazione e inizializzazione
Per avere informazioni in tempo reale sullo stato di attività di ciascun nodo di replicazione, il Proxy
configura ogni gruppo di replicazione in maniera che ogni nodo abbia assegnato un nodo
controllore, il quale ha il compito di interrogarlo periodicamente e notificare il Proxy in caso di
mancata risposta dal nodo controllato.
Caduta di nodo singolo
Durante il funzionamento a regime ogni nodo ha, oltre all’indirizzo del nodo da controllare, anche
l’indirizzo del successore di questo; nel caso in cui il nodo non risponda ad una interrogazione
IS_ALIVE, il controllore passa ad interrogare il nodo successivo.
Per fare in modo che ogni nodo conosca il successore del nodo controllato, ogni messaggio di
risposta IS_ALIVE_OK deve riportare, nel caso in cui il nodo controllato sia cambiato dalla
precedente interrogazione subita, l’indirizzo del nuovo successore.
Nell’ipotesi in cui il tempo che trascorre tra la caduta del nodo e lo scadere del timeout
dell’interrogazione sia inferiore al time-between-failures minimo, questo accorgimento è sufficiente
a garantire il funzionamento corretto di ciascun gruppo di replicazione.
Se invece un nodo riscontra una situazione di fallimento multiplo, ovvero, sia il nodo controllato,
sia il suo successore, non rispondono, comunica la situazione di errore al Proxy con una richiesta di
inizializzazione.
Durante la fase di inizializzazione (illustrata in seguito) il gruppo di replicazione in cui si è
verificato l’errore viene riconfigurato, assegnando nuovamente a ciascun nodo il rispettivo nodo da
controllare tra quelli attivi.
Falsa caduta di un nodo
La mancata ricezione di una risposta al messaggio IS_ALIVE entro il timeout non garantisce che un
nodo sia effettivamente caduto; il nodo in questione potrebbe avere
ritardato la risposta per altre ragioni ed essere ancora attivo.
In una situazione di questo tipo il sistema deve essere in grado di
accorgersi della anomalia ed eseguire una inizializzazione del
gruppo, considerando anche il nodo che era apparentemente caduto.
Per questo motivo ogni nodo memorizza un identificativo del nodo
che è responsabile del suo controllo; questo identificativo viene
aggiornato ogni volta che si riceve un messaggio
IS_ALIVE_NEW_ID, inviato dal nodo che,
riscontrata la caduta del suo successore, passa a
controllare il nodo successivo.
Quando un nodo riceve un messaggio IS_ALIVE da un mittente che ha un
identificativo diverso da quello memorizzato, risponde con un
IS_ALIVE_WRONG_ID, col quale notifica il nodo che l’ha interrogato della sua
uscita dal gruppo di replicazione.
Il nodo che riceve come risposta IS_ALIVE_WRONG_ID può quindi richiedere
al Proxy una nuova inizializzazione.
Inizializzazione
Il Proxy ha il compito di avviare una fase di inizializzazione (durante la quale si riorganizza un
gruppo di replicazione riassegnando le responsabilità di controllo di ciascuno dei nodi attivi) nelle
seguenti occasioni:
 All’avvio del Proxy, per verificare in ogni gruppo di replicazione quali nodi sono attivi e
inizializzarli (quindi anche in caso di caduta e riavvio del Proxy)
 In seguito alla ricezione di una richiesta di inizializzazione da parte di un nodo del gruppo
(che può avvenire sia all’avvio/riavvio di un nodo, sia in caso di ricezione di falsa caduta)
In entrambi i casi il Proxy notifica tutti i nodi del gruppo inviando un messaggio INIT a ciascuno, e
attendendo in risposta un messaggio INIT_OK entro un tempo di timeout, con il quale i nodi
manifestano la loro partecipazione all’inizializzazione.
Ogni nodo che risponde con INIT_OK notifica il Proxy di avere cessato l’interrogazione di un
eventuale nodo controllato con messaggi IS_ALIVE, e di essere in attesa di un messaggio WATCH
con l’indirizzo del nuovo nodo da controllare.
Considerando attivi i soli nodi che rispondono al messaggio INIT entro il timeout, il Proxy
organizza l’anello inviando a ciascun nodo il messaggio WATCH e attendendo risposta; se almeno
uno dei nodi partecipanti non risponde con un messaggio WATCH_OK, l’inizializzazione viene
considerata fallita e ripetuta.
I nodi che ricevono il messaggio WATCH estraggono l’indirizzo inviato dal Proxy e ricominciano
l’interrogazione tramite IS_ALIVE, fino alla successiva ricezione di un messaggio INIT.
4. Il coordinamento delle copie
Ciascun nodo di un gruppo di replicazione è in grado di servire richieste di download e upload
indipendentemente dagli altri nodi; ciascuna operazione quindi agisce sui file memorizzati
localmente sul nodo, senza alcun tipo di comunicazione con gli altri.
Questa scelta è dovuta al fatto che in un sistema di file hosting la prontezza del servizio è uno dei
requisiti principali, ed eseguire un coordinamento con tutti i nodi del gruppo ad ogni richiesta di un
cliente porterebbe a tempi di attesa troppo elevati.
Le fasi di coordinamento delle copie in un gruppo hanno pertanto un duplice scopo:
 Propagare a tutti i nodi i file memorizzati solo sul nodo che ne ha gestito l’upload.
 Garantire che le copie di ciascun file siano identiche su tutti i nodi del gruppo.
Il modello di replicazione dei file è quindi passivo;
File
Contenuto PRIMA del coordinamento
un servizio che esegue in background si occupa di
NodoA
NodoB
NodoC
svolgere periodicamente il coordinamento (ad
text.txt
98 A9 1B…
istanti di checkpoint) senza incidere sui tempi di
video.wmv 80 11 FC… 40 11 FC… 80 11 FC…
risposta alle richieste di upload e download.
archive.zip
12 2D D6
Per queste ragioni il sistema non è in grado di
garantire la consistenza delle copie ad ogni
trasferimento, ma un opportuno dimensionamento
del periodo che intercorre tra un coordinamento e
l’altro permette (scegliendo un compromesso tra
correttezza e tempi di risposta) di garantire un
livello di consistenza adeguato alle esigenze
applicative e alle risorse disponibili.
File
Contenuto DOPO il coordinamento
text.txt
NodoA
98 A9 1B…
NodoB
98 A9 1B…
NodoC
98 A9 1B…
video.wmv
archive.zip
80 11 FC…
12 2D D6
80 11 FC…
12 2D D6
80 11 FC…
12 2D D6
Protocollo di coordinamento – il ruolo del Proxy
Durante il funzionamento del sistema, il Proxy si occupa di verificare lo stato delle operazioni di
coordinamento in corso e di comandarne l’esecuzione in caso in cui sia passato un intervallo di
tempo sufficiente dall’ultimo coordinamento eseguito con successo (il periodo di coordinamento è
un parametro di configurazione del sistema).
Il Proxy inoltre verifica se, nel gruppo che si vuole coordinare, ci sono sufficienti nodi attivi;
il numero di nodi minimo richiesto per il coordinamento è definito a livello applicativo: un valore
elevato riduce le possibilità che gli errori vengano propagati (ad esempio un coordinamento di due
soli nodi non da alcuna garanzia di integrità), viceversa un valore più ridotto permette di mantenere
la coordinazione anche in caso di caduta di un numero consistente di nodi.
Quando si verificano le condizioni richieste per iniziare una fase di coordinamento il Proxy
seleziona uno dei nodi del gruppo da coordinare come coordinatore, inviandogli un messaggio
COORD_START e passando gli indirizzi di tutti i nodi del gruppo che dovrà coordinare.
La scelta di quale nodo tra quelli attivi eleggere coordinatore in ciascuna occasione spetta
all’applicazione, dato che può essere un fattore critico e possono quindi essere utilizzate politiche
volte a bilanciare il carico dei nodi (ad esempio scegliere come coordinatore il nodo che sta
servendo meno richieste, oppure sempre uno stesso nodo dotato di risorse specializzate per
l’operazione).
Ad intervalli regolari il Proxy controlla poi lo stato delle operazioni di coordinamento in corso
inviando a ciascun coordinatore un messaggio COORD_STATUS; se il coordinatore non risponde,
oppure risponde con un messaggio COORD_ERROR, il Proxy considera il coordinamento fallito e
ne inizia uno nuovo sui nodi che in quel momento sono attivi.
Se viceversa riceve in risposta COORD_WAIT, il coordinamento è ancora in corso e quindi non
viene iniziato nessun nuovo coordinamento nel gruppo.
Un messaggio di risposta COORD_SUCCESS significa invece che è stato raggiunto l’accordo sul
contenuto corretto di ciascun file, e tutti i nodi del gruppo contengono copie identiche dello stesso
insieme di file.
Il sistema è quindi tollerante alla caduta del nodo coordinatore, che viene rilevata quando
COORD_STATUS non ottiene risposta, e alla caduta di uno o più nodi partecipanti al
coordinamento, indicata da un messaggio COORD_ERROR da parte del coordinatore.
Nel caso di caduta del Proxy durante il coordinamento, il coordinatore continua ad eseguire
correttamente, e solo al momento del suo riavvio risponde alla interrogazione sullo stato del
coordinamento.
Protocollo di coordinamento – il ruolo del coordinatore
Un nodo che riceve il messaggio COORD_START dal Proxy esegue il coordinamento che consiste
nei seguenti passi:
1. Richiesta della lista dei file e del contenuto dei file da ciascun partecipante al
coordinamento.
2. Scelta, attraverso votazione, del contenuto corretto di ogni file.
3. Richiesta e ricezione di ciascun file del quale il coordinatore abbia una copia corrotta (cioè
con un contenuto diverso da quello considerato valido) da uno dei nodi che ne possiede una
copia integra.
4. Invio delle versioni valide dei file a ciascun nodo partecipante che abbia un contenuto
diverso da quello stabilito.
Solo se tutti questi passi vengono completati correttamente il coordinatore considera l’operazione
completata con successo.
Il primo passo prevede l’invio di un messaggio COORD_GET_LIST a ciascun partecipante; un
servizio in background per le risposte dei messaggi di
coordinamento si occupa di ricevere questo messaggio, recuperare
la lista dei file memorizzati e di rispondere con COORD_LIST.
La lista inviata contiene per ciascun file, oltre all’identificativo
univoco, una stringa che ne riassume il contenuto (l’estrazione del
riassunto da un file è una delle specifiche di livello applicativo; ad
esempio potrebbe essere implementata con una funzione hash
sicura).
Se ciascun partecipante fornisce la sua lista il coordinamento
continua; viceversa se almeno uno non risponde, il coordinamento
fallisce non essendo disponibili tutte le informazioni necessarie per
la votazione.
Durante il secondo passo il coordinatore conta, per ogni diversa
versione del contenuto riassunto di ciascun file, quanti partecipanti
la posseggono eleggendo il più diffuso come copia integra.
Se la copia locale è valida, il coordinatore passa alla quarta fase;
viceversa se il contenuto locale del file differisce dalla versione più
diffusa, richiede con un messaggio FILE_TX_REQUEST l’upload
del file ad uno dei nodi che dispongono di una copia valida.
Al termine del trasferimento, estrapolando dal file ricevuto la
stringa riassuntiva e confrontandola con quella maggiormente
votata, verifica se è possibile passare alla fase di propagazione.
Infine, con un messaggio FILE_TX_REQUEST (in questo caso
con un attributo che indica “upload”) richiede al nodo l’upload del file, che andrà a sovrascrivere
un’eventuale copia già presente e gli trasmette anche la stringa riassuntiva.
Al termine di questo trasferimento il coordinatore attende un messaggio di risposta
FILE_TX_SUCCESS, per avere la garanzia che il file ricevuto dal partecipante ha un contenuto
conforme alla stringa riassuntiva inviatagli.
Protocollo di coordinamento – il partecipante passivo
Ciascun nodo dispone di un servizio di trasferimento file in background che, secondo il protocollo
di coordinamento, riceve le richieste di upload o download provenienti dal coordinatore.
Questo servizio è in grado di soddisfare più richieste contemporanee, e garantisce che non vi siano
interferenze nelle operazioni di scrittura.
Inoltre può ricevere messaggi di tipo COORD_START (provenienti dal Proxy) e
COORD_GET_LIST (provenienti dal coordinatore).
E’ importante che ad ogni istante sia attivo al più un coordinatore per ogni gruppo, per evitare
problemi di consistenza nel caso in cui le decisioni prese dai diversi coordinatori riguardo le
versioni corrette dei file fossero in contraddizione.
Questa situazione può verificarsi se il Proxy, una volta avviato un coordinatore, cade e, una volta
riavviato, non sapendo che è già in funzione un coordinamento, elegge un nuovo coordinatore.
Lo stesso può capitare anche nel caso di “falsa caduta” del nodo coordinatore, ovvero se
l’interrogazione COORD_START non riceve risposta entro il tempo di timeout nonostante il
coordinatore sia in funzione.
Per questa ragione se un nodo coordinatore riceve COORD_GET_LIST (da un altro “aspirante”
coordinatore) risponde con un messaggio di errore, in maniera da costringere questo a terminare con
un fallimento.
5. L’interazione con i clienti
Come già illustrato nella panoramica sull’architettura del sistema, l’interazione dei clienti con il
sistema avviene in due momenti:
 Nel contattare il Proxy che fa da front-end del sistema, ricevendo le informazioni che
permettono di contattare il nodo servitore scelto
 Nell’invocazione dell’operazione sul nodo servitore
Le due comunicazioni avvengono senza alcun coordinamento tra Proxy e nodo scelto; questo
permette di evitare un notevole overhead di comunicazione, che inciderebbe sui tempi di risposta
agli occhi del cliente, ma, allo stesso tempo, richiede alcuni accorgimenti per garantire un servizio
affidabile.
Scelta del nodo servitore
Il Proxy, una volta ricevuta una richiesta di upload o download, è in grado di selezionare il gruppo
di replicazione corrispondente al file richiesto, a seconda delle politiche di partizionamento della
capacità di memoria.
All’interno del gruppo, però, la scelta dello specifico nodo servitore per le operazioni di download
non è del tutto libera: come visto nel capitolo sul coordinamento, è infatti possibile che un file sia
memorizzato solo sul nodo che ne ha gestito l’upload non essendo ancora stato propagato agli altri
membri del gruppo.
Questo significa che il Proxy deve sapere, per ogni upload eseguito in passato, quale nodo del
gruppo ha ricevuto il file, e deve mantenere lo stato dei coordinamenti eseguiti su quel gruppo (per
sapere quali file sono stati propagati a tutti i membri e quali invece sono memorizzati solo
localmente al nodo che li ha ricevuti).
Per permettere questo il Proxy marca ciascuna operazione di upload (quindi ciascun file ricevuto)
con un timestamp, ovvero una stringa che codifica l’istante di tempo della ricezione della richiesta.
Inoltre, anche ogni coordinamento comandato dal Proxy ha come parametro un timestamp, che
viene passato al nodo coordinatore tramite COORD_START e successivamente restituito tramite il
messaggio COORD_SUCCESS di risposta all’interrogazione del Proxy.
Il coordinatore si occupa di eseguire il coordinamento dei soli file che abbiano un timestamp di
upload che indichi un istante precedente a quello del timestamp di coordinamento.
Il Proxy, alla ricezione di un messaggio COORD_SUCCESS indicante un certo timestamp,
considera già propagati ai membri del gruppo tutti i file che hanno un timestamp di upload
precedente a quello del coordinamento.
Per potere smistare correttamente le richieste di download il Proxy deve solo memorizzare una lista
dei file temporaneamente “non ancora propagati” e, per ciascuno, il nodo che lo ha memorizzato
localmente; ad ogni coordinamento terminato con successo scarta da questa lista tutti i file con un
timestamp di upload precedente a quello del coordinamento eseguito.
Questo meccanismo non da l’assoluta certezza che i file considerati propagati siano effettivamente
presenti su tutti i nodi del gruppo.
Ad esempio, se un upload con un timestamp X viene effettivamente terminato dopo un
coordinamento eseguito con timestamp Y con X < Y, allora questo file non verrà propagato agli altri
membri del gruppo fino al successivo coordinamento.
Del resto il sistema non garantisce il servizio di tutte le richieste provenienti dai clienti; questa
ipotesi non è particolarmente stringente dato che nel tipico scenario applicativo di un sistema di File
Hosting, il fallimento di una richiesta è un disservizio tollerabile.
La semantica riguardo al servizio delle richieste si potrebbe pertanto definire “at most once”.
Passaggio dei parametri di invocazione
Al momento della redirezione del cliente al nodo servitore incaricato di eseguire la sua richiesta, il
Proxy gli fornisce, oltre all’indirizzo che gli permetterà di mettersi in comunicazione con questo,
anche i parametri di invocazione.
Questi parametri contengono l’identificativo unico del file, un’indicazione sul tipo di trasferimento
(download/upload), e, solo in caso di upload, il timestamp assegnato a quel file.
La codifica di questa tupla sotto forma di stringa spetta al livello applicativo; ad esempio potrebbe
essere richiesta una codifica che la renda opaca al cliente, oppure una qualche forma di
autenticazione del Proxy che possa essere verificata dal nodo ricevente.
6. Utilizzo del supporto
In questo capitolo vengono illustrate le interfacce attraverso cui il progettista di un sistema di File
Hosting può specificare il comportamento, le politiche e i protocolli personalizzati in base alle
esigenze applicative.
Implementazione di un Proxy
La classe Proxy rappresenta il generico Proxy; per definire una istanza di questa classe devono
essere forniti, oltre ai parametri di configurazione (tra cui i tempi di timeout, la struttura dei gruppi
di replicazione, gli indirizzi e le porte da utilizzare per le comunicazioni interne) i seguenti oggetti:
 Un oggetto di tipo FileHostingService che definisce la comunicazione con i clienti e la
redirezione delle richieste verso i nodi servitori.
Il metodo principale che deve essere implementato per questa classe astratta è
FileRequestConnection acceptConnection()
che deve ascoltare e ricevere una connessione da un cliente sulla quale verrà eseguita la
comunicazione per ricevere la richiesta e reindirizzare il cliente.
L’oggetto restituito (di tipo FileRequestConnection) deve fornire, a seconda del
protocollo utilizzato per comunicare con il client un’implementazione ai metodi:
FileOperation receiveRequest()
//Legge e interpreta i parametri della richiesta
void sendFileLink(Node selectedNode, String encodedRequest)
//Invia un indirizzo per la redirezione e i parametri di invocazione
void sendErrorNotification(Exception exception)
//Notifica di un errore avvenuto sul proxy
Oltre a questi il FileHostingService deve fornire implementazione ai metodi per la scelta
del gruppo di replicazione associato ad un certo file, e la scelta del nodo di servizio tra quelli
attivi (quest’ultimo metodo viene invocato solo nel caso in cui il file sia già stato propagato
a tutto il gruppo).
 Un oggetto che implementi l’interfaccia FileNamer, che espone metodi per la scelta degli
ID univoci dei file, per la lettura e il confronto di timestamp, e per la codifica/decodifica dei
parametri di invocazione.
 Un CoordinationManager. Questa classe astratta richiede l’implementazione del metodo
(invocato ogni volta che si verificano le condizioni per avviare un coordinamento) che
sceglie, tra i nodi attivi di un gruppo, il coordinatore.
Implementazione di un nodo di replicazione
La costruzione di un GroupNode (che gestisce un nodo di replicazione) richiede, oltre ai parametri
di configurazione del nodo:
 Un FileTransferService che, in maniera simile a FileHostingService apre una
connessione con il cliente per servire le richieste.
La connessione creata è in questo caso di tipo FileTransferConnection e deve fornire,
una volta aperta, gli stream di input e di output per leggere o scrivere il file da trasferire, e i
parametri di invocazione ricevuti (codificati dal Proxy).
 Un oggetto che implementi FileManager. Questa interfaccia definisce le modalità di
memorizzazione locale dei file (anche questo dipende dalle esigenze applicative: potrebbe
essere usato un database ad esempio); ha quindi metodi per l’apertura in lettura o in scrittura
di file, per il salvataggio delle modifiche e per l’annullamento delle modifiche fatte.
Inoltre espone i metodi per il calcolo della stringa riassuntiva del contenuto dei file (ad
esempio tramite funzione hash), per ottenere l’elenco dei file memorizzati e i timestamp.
 Un oggetto di tipo FileNamer come quello usato dal Proxy (usato per decodificare i
parametri di invocazione ricevuti).
Applicazione di prova
E’ stata sviluppata una applicazione di test che è stata utilizzata per provare il sistema in diverse
possibili configurazioni e per il debugging.
Questa applicazione fornisce un’implementazione molto semplificata alle interfacce sopra elencate;
realizza la comunicazione tra i client e i nodi del sistema tramite socket TCP e realizza un
bilanciamento del carico smistando in maniera omogenea i file sui gruppi di replicazione e le
richieste sui membri di ciascun gruppo.
La memorizzazione dei file è eseguita con una scrittura e lettura sul file system locale (il
meccanismo di annullamento delle modifiche viene gestito usando dei file temporanei), le stringhe
riassuntive sono calcolate con SHA, e i parametri di invocazione vengono passati ai clienti in
chiaro.
7. Possibili sviluppi futuri
Questo progetto, che nasce con l’idea di facilitare la costruzione di sistemi di File Hosting, ha
messo in evidenza alcuni settori su cui si potrebbe lavorare per migliorare il supporto al progettista.
Risaltano soprattutto i problemi cui questo sistema andrebbe incontro se usato in ambienti al limite
delle capacità computazionali o di memoria.
Per migliorarne il funzionamento si potrebbe pensare di introdurre una serie di meccanismi per la
Quality of Service, a partire dai quali il progettista potrebbe realizzare delle politiche di gestione del
sistema che mirino a differenziare la quantità di risorse stanziate per la gestione di ciascuna
richiesta.
In questo senso potrebbe tornare utile un sistema di monitoraggio della capacità residua su ciascun
nodo, che permetta di inserire politiche di reazione o di azione preventiva allo scopo di evitare il
riempimento della memoria.
Scartando alcuni file (ad esempio quelli che non sono richiesti da molto tempo, oppure quelli meno
importanti) in condizioni critiche, si potrebbe liberare dello spazio, ma si perderebbe la garanzia di
persistenza.
Un’altra dimensione della qualità di servizio è quella della gestione del traffico e del problema di
come suddividere la banda disponibile tra le diverse operazioni di trasferimento in corso.
Molti servizi di Web File Hosting, soprattutto quelli disponibili gratuitamente, prevedono code
presso cui i clienti vengono messi in attesa del loro turno per eseguire il trsferimento; a volte si
adottano politiche personalizzate di gestione delle code, che danno la precedenza a determinate
richieste (ad esempio quelle provenienti da clienti paganti, oppure quelle per file di dimensioni
ridotte).
BIBLIOGRAFIA
Lucidi del corso di Reti di Calcolatori L-S del Prof. A.Corradi
A.S. Tanenbaum, M.van Steen, Distributed Systems: Principles and Paradigms, Prentice-Hall 2002.