Supporto per la replicazione attiva di servizi Progetto per il corso di Reti di Calcolatori LS Montanari Mirko Matr:
Scopo del progetto Creare una estensione di Jeri, meccanismo di invocazione remota di Java, in modo da consentire una (quasi) trasparente replicazione attiva di un servizio remoto. Attualmente Java non fornisce meccanismi per replicare servizi offerti attraverso invocazione remota. Utilizzando l’infrastruttura sviluppata è molto semplice convertire un servizio qualunque in un servizio replicato. In questa presentazione … Funzionamento ed architettura del sistema Come è stato realizzato estendendo un meccanismo di invocazione remota di Java Piccolo servizio di esempio
Replicazione Attiva Normalmente una invocazione remota in Java è strutturata come segue: Invocazione remota di un servizio Nel caso della replicazione attiva si vuole che la richiesta di servizio non sia eseguita soltanto da un calcolatore, ma da un gruppo di repliche. Replicazione attiva: Tutti eseguono l’operazione richiesta e si accordano per il risultato da restituire al cliente
Requisiti del supporto Replicazione attiva Maggiore resistenza ai guasti: Se il gruppo è formato da 3t repliche, può tollerare guasti bizantini su t di esse Ognuna delle repliche del servizio può anche implementare algoritmo diversi Supporto trasparente Scrivere un cliente che utilizza un servizio replicato deve essere equivalente a scrivere un normale cliente che usa un servizio remoto nomale. Adattare un servizio alla replica deve essere una operazione semplice e legata alla logica del servizio stesso. Ciò che non dipende dalla logica del servizio deve essere svolto dal supporto.
Funzionamento del sistema Il cliente deve interagire come se stesse dialogando con un servizio non replicato Interazione con un coordinatore 1. Arrivo richiesta 2. Coordinazione copie 3. Esecuzione 4. Accordo finale 5. Risposta al cliente E in caso di guasto? Ingresso ed uscita di repliche dal gruppo è gestito da ogni replica comunicando con il master Servizio dei nomi Coordinatore Cliente Richiesta con id univoco Fasi dell’interazione:
Guasti al sistema Durante il funzionamento del sistema possono verificarsi guasti. Condizione di funzionamento del sistema: Almeno una replica ed un servizio dei nomi raggiungibile dai client. Tipologie di guasto tollerate: Sistema di 3t risorse tollera t guasti bizantini Il guasto non deve però presentarsi nella fase di raccolta e distribuzione delle richieste da parte del coordinatore. E’ tollerato un guasto fail-safe. Network partitioning: ogni partizione che rispetta la condizione di funzionamento può continuare ad erogare il servizio Guasti possibili: Guasto ad uno dei membri del gruppo Fallimento del coordinatore Network partitioning Coordinatore Nuova view
Fallimento del coordinatore (Server) Ogni partecipante al gruppo ha un numero univoco che lo identifica Elezione attuata attraverso l’algoritmo bully per funzionare con invocazione remota sincrona e bloccante. Coordinatore (fallito) ID: 12 1: ping 2: election 3: election 4: election coordinator L’errore in un ping fa iniziare il processo di elezione Group Member ID: 9 Group Member ID: 4 Group Member ID: 1 Si accorge di essere il membro con il più alto id della view e si dichiara nuovo coordinatore Coordinatore eletto fra i membri del gruppo
Fallimento del coordinatore (Client) Al fallimento del coordinatore anche il cliente perde il suo interlocutore. Deve essere fatta una nuova interrogazione al servizio dei nomi per ottenere il riferimento al nuovo coordinatore Procedura effettuata in automatico dallo stub del cliente. Vecchio coordinatore Nuovo coordinatore id: 342 La presenza di un identificativo univoco di ogni richiesta impedisce che la richiesta sia eseguita più volta Semantica at-most-once
Partizionamento della rete Il partizionamento è un fallimento che dividono le rete in due partizioni. I calcolatori che sono all’interno della stessa partizione possono comunicare fra di loro, ma non con altri contenuti in altre partizioni. Ogni partizione deve contenere un servizio dei nomi e una delle repliche Coordinatore ping Coordinatore elezione New view
Merge di due partizioni Quando un guasto di partizionamento viene risolto, il sistema si trova contemporaneamente ad avere due coordinatori. Inoltre ognuno dei due gruppi di repliche è evoluto indipendentemente l’uno dall’altro. Necessario un coordinamento per riportare il sistema ad avere un solo coordinatore ed un solo stato. Il calcolo dello stato finale viene demandato alla implementazione del servizio. Coordinatore ID: 56 Coordinatore ID: 32 Calcolo del nuovo stato Richiede stato e view corrente unregister Invio della nuova view e stato a tutti
Realizzazione: integrazione con Jeri Jeri è una implementazione di RMI alternativa alla standard di Java. Basato su Jini Consente l’estendibilità del modo in cui l’invocazione viene effettuata. Il progetto modifica il funzionamento di: Skeleton: per implementare la distribuzione della richiesta ricevuta dal cliente alle repliche Stub: per consentire la ricerca del nuovo coordinatore al fallimento del vecchio
Stub e Skeleton di Jeri A differenza di RMI standard stub e skeleton vengono generati dinamicamente. Lo stub è scaricato dal client alla richiesta del riferimento al coordinatore Stub e skeleton di Jeri divisi in livelli: Trasport Layer: codica della richiesta e della risposta in maniera che possa essere inviata attraverso la rete Object Identification Layer: Più oggetti possono essere attivati sullo stesso trasporto. Questo layer si occupa di indirizzare la richiesta all’oggetto giusto. Invocation Layer: A lato client rende trasparente l’invocazione di un servizio remoto e, a lato server, invoca l’effettivo metodo di business.
Livelli di Jeri Programma Cliente Trasport level Object identification layer Group Invocation handler Invocation handler Trasport level Object identification layer Group invocation dispatcher Invocation dispatcher Servizio Coordinatore Servizio Group Member Livelli standard di Jeri Invocazioni remote con Jeri
Applicazione di esempio Implementato un semplice servizio di Rubrica per dimostrare il funzionamento del supporto Oltre ai metodi di business ogni servizio deve implementare: setState(Serializable state): utilizzato per impostare lo stato iniziale della replica. getState(Serializable state): utilizzato dal coordinatore per avere lo stato attuale della propria replica del servizio. joinState(Serializable state): in caso di merge di due partizioni al servizio viene passato lo stato dell’altra partizione. L’applicazione deve provvedere a creare uno stato che tenga conto di entrambi (se possibile..)
Conclusioni Il supporto sviluppato permette la replicazione attiva di un servizio java, attraverso una estensione di Jeri. Resistente ai guasti: Può tollerare vari tipi di guasto alle repliche ed è in grado di funzionare anche in caso di partizionamento Trasparente: Non richiede nessuna modifica ad un client jeri e poche modifiche nella implementazione del servizio. Sviluppi futuri Supporto nella concorrenza delle invocazioni. Attualmente un solo client alla volta può invocare il servizio Scaricare il coordinatore dall’onere di dover rispondere alle richieste di sola lettura. Potrebbero essere gestite dalla replica più vicina Utilizzo di meccanismi per la comunicazione di gruppo (multicast) per le comunicazioni fra il coordinatore e il resto del gruppo.