640 likes | 819 Views
Peer to Peer Computing e Distributed Hash Table (DHT). Giancarlo Ruffo Dipartimento di Informatica Università di Torino. Obiettivi del P2P. Obiettivi del Peer-to-Peer. Riduzione/Condivisione dei costi Ogni peer è responsabile dei propri costi Napster: riduzione dei costi di memorizzazione
E N D
Peer to Peer Computing e Distributed Hash Table (DHT) Giancarlo Ruffo Dipartimento di Informatica Università di Torino P2P e DHT - G. Ruffo
Obiettivi del P2P P2P e DHT - G. Ruffo
Obiettivi del Peer-to-Peer • Riduzione/Condivisione dei costi • Ogni peer è responsabile dei propri costi • Napster: riduzione dei costi di memorizzazione • SETI@home: riduzione dei costi computazionali • Miglioramento della scalability/affidabilità • Nuovi algoritmi (CAN, Chord, etc.) sono stati progettati a questo scopo P2P e DHT - G. Ruffo
Obiettivi del Peer-to-Peer • Aggregazione delle risorse • Ogni peer presta le sue risorse alla rete • Napster: Condivide file e banda • Seti@home: Condivide risorse computazionali • Maggiore autonomia • Nessun provider centralizzato di servizi • I task sono eseguiti localmente P2P e DHT - G. Ruffo
Obiettivi del Peer-to-Peer • Anonimato/Privacy • Con un server centrale, è difficile garantire l’anonimato • I sistemi P2P eseguono locamente i task, così i peer possono evitare di fornire tutte le informazioni in loro possesso • FreeNet: Non è possibile localizzare chi ha generato una richiesta • Altri esempi: Tarzan, Publius, etc. P2P e DHT - G. Ruffo
Obiettivi del Peer-to-Peer • Dinamicità • Nel P2P i nodi, e quindi le risorse, entrano ed escono dal sistema continuamente ed in modo trasparente • Comunicazioni Ad-hoc • I membri del sistema possono entrare ed uscire dal sistema indipendentemente dalla loro ubicazione e dal loro interesse P2P e DHT - G. Ruffo
Overlay network Overlay networks Internet P2P e DHT - G. Ruffo
Misure per le prestazioni • Degree • Il numero di vicini (neighbors) con i quali un nodo mantiene contatti continui • Hop count • Il numero di “hops” necessari ad un messaggio per raggiungere una destinazione qualsiasi da una qualsiasi provenienza • Il grado di fault tolerance • Che frazione di nodi può fallire senza che dei dati vengano eliminati o che venga compromesso un routing efficace • Il maintenance overhead • Quanto spesso i nodi vicini si scambiano messaggi per mantenere lo stato attuale, anche rispetto ai vari “join” e “leave” • Il grado di load balance • Quanto uniformemente vengono distribuite le chiavi tra i nodi, e quanto carico ogni nodo deve sopportare se usato come intermediario durante un routing P2P e DHT - G. Ruffo
lookup (”xyz”) Object Object Object Object Object Object Object Object download Object Object Object Object reply (”host3”) Publish (”I have xyz”) Centralized server Host4 Host1 Host5 Network Host2 Host3 Server P2P e DHT - G. Ruffo
Esempi • Napster, WinMx, DC++ P2P e DHT - G. Ruffo
Prestazioni • Solo il server deve mantenere uno stato del sistema • Vantaggi • Lookup veloce (O(1)) • Svantaggi • Single point of failure (Napster lo ha dimostrato abbastanza bene) P2P e DHT - G. Ruffo
Flooding (1/2) • Se non hai quello che vuoi (e.g. file), manda una query ad n dei tuoi nodi partner. • Se anche loro non hanno quello che cerchi, contatteranno n dei loro partner, per un hop count massimo uguale a k. • E.g., n = 7, k = 10 • Le richieste vengono mandate in “broacasting” • In generale, nessuna struttura ad albero • Il looping viene evitato, ma i pacchetti possono essere ricevuti più volte. P2P e DHT - G. Ruffo
Object Object Object Object Object Object Object Object Object Object Object Object Flooding (2/2) Host7 Host4 Host1 Host5 Network Host2 Host3 Host6 P2P e DHT - G. Ruffo
Esempi • Gnutella • KaZaa (gerarchico) P2P e DHT - G. Ruffo
Prestazioni • Nessun limite superiore per lo stato (degree); • Nessuna garanzia di trovare la risorsa cercata (anche se esistente); • L’overhead per il mantenimento è alto (fenomeno topology mismatch…) • Grado di Fault Tolerance: dipende… • Resistente ai guasti casuali • Debole contro attacchi mirati (DoS) P2P e DHT - G. Ruffo
Algoritmi P2P:Tabelle Hash Distribuite P2P e DHT - G. Ruffo
Sommario • Introduzione • Casi di studio • Chord • Panoramica • Applicazioni: DHASH, Arpeggio, CFS, The Circle • Kademlia • Panoramica • Applicazioni: eMule, Overnet, RevConnect DC++, KadC P2P e DHT - G. Ruffo
Distributed Hash Tables (DHTs) • Le tabelle hash associano Chiavi a Valori • Le DHTs sono overlay strutturate che offrono: • Alta scalabilità • Interfaccia per il lookuphash-table-like • Un sistema DHT supporta una funzionalità simile ad una tabella hash su scala Internet-like • Substrato ideale per molte appliciazioni (P2P) • file-systems, storage, backups, event-notification, e-mail, chat, databases, sensor networks ... P2P e DHT - G. Ruffo
Distributed Hash Tables (2) • Il nucleo di ogni sistema DHT: • Overlay network • Algoritmo di routing • Funzione hash • Problema principale: lookup • Come trovare (efficientemente) la posizione di un oggetto (e.g. a file) • Quando si conosce la posizione, il download è diretto • Inoltre, si devono suddividere i dati in modo tale che le operazioni di joins/leaves richiedano uno lavoro minimo P2P e DHT - G. Ruffo
DHT: schema generale Es. lookup(K431) = V6 P2P e DHT - G. Ruffo
Chord P2P e DHT - G. Ruffo
Chord • Semplice protocollo per lookup distributa • Una sola operazione: associa una chiave ad un nodo • Sviluppato al MIT (IRIS Project) • Ogni nodo mantiene informazioni di routing di circa O(log N) • Messaggi necessari per trovare un nodo: O(log N) • Messaggi necessari per aggiornare le informazioni di routing: O(log2 N) P2P e DHT - G. Ruffo
Chord – Consistent Hashing • Ad ogni nodo e ad ogni chiave viene assegnato un id a m bit. (m = 160 per SHA-1) • n = nodeID = H(IP address) • k = keyID = H(key) • ID ordinati in un anello modulo 2m • successor (k) è il primo nodo con n ≥ k P2P e DHT - G. Ruffo
0 7 1 2 6 3 5 4 Chord – Consistent Hashing m = 3 k1 = 1 k2 = 2 k3 = 6 P2P e DHT - G. Ruffo
Chord – Scalable Key Location • m è la dimensione in bit degli ID • Ogni nodo n mantiene una finger table con (max) m entry. • L’entry i-esima sul nodo n contiene l’ID del primo nodo s che succeda n di almeno 2i – 1. • s = successor (n + 2 i – 1) • s = n.finger[i].node P2P e DHT - G. Ruffo
Chord – Scalable Key Location • Ogni nodo mantiene informazioni su pochi altri nodi. • Una finger table di un nodo NON ha solitamente informazioni sufficienti per determinare il successor di una chiave arbitraria. P2P e DHT - G. Ruffo
Chord: Finger table per il nodo 109 N5 N123 N7 with m = 7 N109 N20 N98 N33 N90 N45 N81 N60 P2P e DHT - G. Ruffo
finger[k].start (n + 2k-1) mod 2m finger[k].interval [finger[k].start, finger[k+1].start) finger[k].node the 1st node ≥ n.finger[k].start successor next node on ID circle predecessor prev node on ID circle Chord – Scalable Key Location RPC eseguita sul nodo n n.find_successor(id) n’ = find_predecessor(id); return n’.successor; n.find_predecessor(id) n’ = n; while (id not in (n’ , n’.successor]) n’ = n’.closest_preceding_finger(id); return n’; n.closest_preceding_finger(id) for i = m downto 1 if (finger[i].node in (n, id)) return finger[i].node; return n; RPC eseguita per cercare la variabile “successor” su n’ I puntatori della finger table, raddoppiando continuamente le distanze, causano il dimezzamento della distanza dall’obiettivo. P2P e DHT - G. Ruffo
0 7 1 2 6 3 5 4 Chord – Scalable Key Location finger[3].interval = [finger[3].start, 1) finger[1].start = 2 finger[1].interval = [finger[1].start, finger[2].start) finger[3].start = 5 finger[2].start = 3 finger[2].interval = [finger[2].start, finger[3].start) P2P e DHT - G. Ruffo
0 7 1 2 6 3 5 4 Chord – Scalable Key Location Finger TABLE Finger TABLE KEY = 1 Finger TABLE KEY = 6 Lookup(1) KEY = 2 P2P e DHT - G. Ruffo
Chord – Node Joins 2 INVARIANTI • Il successore di ogni nodo è mantenuto correttamente • Per ogni k, il nodo successor(k) è responsabile per k. P2P e DHT - G. Ruffo
Predecessor pointer Chord – Node Joins Ogni nodo che entra o esce dal sistema causa l’invio di O(log2 N) messaggi lungo l’anello per correggere le finger table. P2P e DHT - G. Ruffo
Chord – Node Joins n entra nella rete. Occorre: • Riferirsi ad un nodo di bootstrap (n’) • Inizializzare predecessor e finger (tramite lookup apposite eseguite da n’) • Aggiornare i finger e i predecessori dei nodi nella rete • Avvertire il livello sw superiore in modo che possa spostare le chiavi. P2P e DHT - G. Ruffo
Chord – Node Joins #define successor finger[1].node n.join(n′) if(n′) init_finger_table(n′); update_others(); else for i = 1 to m finger[i].node = n; predecessor = n; n.init_finger_table(n′) finger[1].node = n′.find_successor(finger[1].start); predecessor = successor.predecessor; successor.predecessor = n; for i = 1 to m – 1 if (finger[i + 1].start in [n, finger[i].node)) finger[i + 1].node = finger[i].node else finger[i + 1].node = n′.find_successor(finger[i + 1].start); n.update_others() for i = 1 to m p = find_predecessor(n – 2i – 1); p.update_finger_table(n,i); n.update_finger_table(s,i) if (s in [n, finger[i].node]) finger[i].node = s; p = predecessor; p.update_finger_table(s,i); P2P e DHT - G. Ruffo
0 7 1 2 6 3 5 4 Chord – Node Joins Finger TABLE Finger TABLE KEY = 1 KEY = 6 Finger TABLE Finger TABLE KEY = 2 P2P e DHT - G. Ruffo KEY = 6
0 7 1 2 6 3 5 4 Chord – Node Joins Finger TABLE Finger TABLE KEY = 1 KEY = 6 Finger TABLE Finger TABLE KEY = 2 P2P e DHT - G. Ruffo KEY = 6
0 7 1 2 6 3 5 4 Chord – Node Leaves Finger TABLE Finger TABLE KEY = 1 KEY = 6 Finger TABLE Finger TABLE KEY = 2 P2P e DHT - G. Ruffo KEY = 6
0 7 1 2 6 3 5 4 Chord – Node Leaves Finger TABLE KEY = 6 Finger TABLE Finger TABLE KEY = 1,2 P2P e DHT - G. Ruffo KEY = 6
7 5 6 Chord - Stabilization stabilization successor predecessor successor P2P e DHT - G. Ruffo
DHash P2P e DHT - G. Ruffo
DHash • Chord non fornisce STORAGE • err_t insert (void *key, void *value) void *lookup (void *key) • k = H(key) per produrre un ChordID di 160 bit e memorizzando il valore (value) nel nodo successor(k) P2P e DHT - G. Ruffo
DHash - Reliability • Per preservare l’invariante del mantenimento della chiave sul successor -> callback di Chord. • Spostamento di O(1/N) chiavi ogni volta che un nodo entra o esce dal sistema, a cui si deve aggiungere il costo O(log N) • Memorizzazione non solo su successor(k) ma anche sui primi r successor -> redundant storage P2P e DHT - G. Ruffo
DHash - Performance • I cammini che cercano un determinato successor, partendo da nodi diversi, tendono ad incrociarsi tanto più frequentemente quanto più ci si avvicina al target. • Per ogni lookup di (k,v) che ha successo il valore v viene mantenuto in cache dai nodi sul percorso. • Le lookup successive vanno a cercare il v in cache. • + popolarità = + diffusione P2P e DHT - G. Ruffo
DHash - DoS • Inserimento grandi quantità dati inutili —> flush dei dati interessanti. Contromossa: limitare il numero di blocks che un nodo può mantenere. • Un nodo si annuncia come successor e poi non memorizza il file: controllo di n da parte degli altri nodi. • Controllo incrociato per verificare la correttezza della coppia (successor, predecessor). P2P e DHT - G. Ruffo
DHash – Balancing Load • Caching • Layer of indirection: DHash mappa gli ID dei file in una lista di IP dove il documento è disponibile (DNS-like). Problema: caching e redundant storage devono essere implementati due volte. P2P e DHT - G. Ruffo
DHash – Balancing Load • Vengono mappati blocks di file invece dei file interi. • I file sono inseriti a livello DHash usando come chiave l’hashing del contenuto del block. • Meta-data (come inode) per fornire un nome unico per il file completo. • I file vengono sparsi su molti server, e quindi c’è un bilanciamento di carico. • Aumento affidabilità e performance. P2P e DHT - G. Ruffo
DHash – Balancing Load • Dal momento che per un file devono essere contattati più nodi, dobbiamo pagare un costo in più per i DHash lookup ulteriori. • Un’implementazione base costa: (S x L x log N) / B S (byte) = document size, N = numero server, B = block size, L = average latency P2P e DHT - G. Ruffo
DHash API • put_h(block): calcola la chiave del blocco calcolando il suo hash (key= hash(block)), e lo spedisce al nodo sucessore (succ(key)) per effettuare lo storage; • get(key): individua e restituisce il blocco associato alla chiave Chord specificata. P2P e DHT - G. Ruffo
CFS – Cooperative FS P2P e DHT - G. Ruffo
Ricerca per keyword in una DHT • Se si conosce l’hash del file, lo si trova in tempo O(logN); • Ma se non si conosce l’hash? • Non banale: l’uso degli hash crittografici complica tutto (no collisioni, basta cambiare un bit, per avere un hash completamente diverso …) • DHT ottime per load balancing, ma pessime per la ricerca via keyword P2P e DHT - G. Ruffo